/src/ghostpdl/pdf/pdf_font1C.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2019-2022 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., 1305 Grant Avenue - Suite 200, Novato, |
13 | | CA 94945, U.S.A., +1(415)492-9861, for further information. |
14 | | */ |
15 | | |
16 | | /* code for CFF (type 1C) font handling */ |
17 | | |
18 | | #include "pdf_int.h" |
19 | | |
20 | | #include "gscedata.h" |
21 | | #include "gscencs.h" |
22 | | #include "gxfont0.h" |
23 | | #include "gxfcid.h" |
24 | | |
25 | | #include "pdf_types.h" |
26 | | #include "pdf_font_types.h" |
27 | | #include "pdf_font.h" |
28 | | #include "pdf_font1C.h" |
29 | | #include "pdf_fontps.h" |
30 | | #include "pdf_dict.h" |
31 | | #include "pdf_deref.h" |
32 | | #include "pdf_file.h" |
33 | | #include "pdf_array.h" |
34 | | |
35 | | #include "gxtype1.h" /* for gs_type1_state_s */ |
36 | | #include "gsutil.h" /* For gs_next_ids() */ |
37 | | |
38 | | static byte * |
39 | | pdfi_find_cff_index(byte *p, byte *e, int idx, byte **pp, byte **ep); |
40 | | |
41 | | /* This is a super set of the contents of a pdfi Type 1C font/CIDFont. |
42 | | Meaning we can store everying as we interpret, and not worry |
43 | | about the actual font type until the end |
44 | | */ |
45 | | typedef struct pdfi_cff_font_priv_s { |
46 | | pdf_font_common; |
47 | | pdf_array *Subrs; |
48 | | int NumSubrs; |
49 | | pdf_array *GlobalSubrs; |
50 | | int NumGlobalSubrs; |
51 | | pdf_dict *CharStrings; |
52 | | byte *cffdata; |
53 | | byte *cffend; |
54 | | byte *gsubrs; |
55 | | byte *subrs; |
56 | | byte *charstrings; |
57 | | int ncharstrings; |
58 | | pdf_dict *CIDSystemInfo; |
59 | | int64_t DW; |
60 | | pdf_array *W; |
61 | | pdf_array *DW2; |
62 | | pdf_array *W2; |
63 | | pdf_buffer *cidtogidmap; |
64 | | pdf_array *FDArray; |
65 | | /* The registry and ordering strings in gs_font_cid0_data are just references to |
66 | | strings assumed to be managed be managed by the interpreter - so we have to stash |
67 | | them in the pdfi font, too. |
68 | | */ |
69 | | pdf_string *registry; |
70 | | pdf_string *ordering; |
71 | | int supplement; |
72 | | int cidcount; |
73 | | int uidbase; |
74 | | font_proc_glyph_info((*orig_glyph_info)); |
75 | | } pdfi_cff_font_priv; |
76 | | |
77 | | /* Same thing for the Ghostscript font |
78 | | */ |
79 | | typedef struct pdfi_gs_cff_font_priv_s { |
80 | | gs_font_base_common; |
81 | | gs_type1_data type1data; |
82 | | gs_font_cid0_data cidata; |
83 | | bool forcecid; |
84 | | pdfi_cff_font_priv pdfcffpriv; |
85 | | } pdfi_gs_cff_font_priv; |
86 | | |
87 | | typedef struct pdfi_gs_cff_font_common_priv_s { |
88 | | gs_font_base_common; |
89 | | } pdfi_gs_cff_font_common_priv; |
90 | | |
91 | | typedef struct cff_font_offsets_s |
92 | | { |
93 | | unsigned int fdarray_off; |
94 | | unsigned int fdselect_off; |
95 | | unsigned int charset_off; |
96 | | unsigned int encoding_off; |
97 | | unsigned int strings_off; |
98 | | unsigned int strings_size; |
99 | | unsigned int private_off; |
100 | | unsigned int private_size; |
101 | | bool have_ros; |
102 | | bool have_matrix; |
103 | | } cff_font_offsets; |
104 | | |
105 | | static int |
106 | | pdfi_make_string_from_sid(pdf_context *ctx, pdf_obj **str, |
107 | | pdfi_cff_font_priv *font, cff_font_offsets *offsets, unsigned int sid); |
108 | | |
109 | | static void |
110 | | pdfi_init_cff_font_priv(pdf_context *ctx, pdfi_gs_cff_font_priv *cffpriv, |
111 | | byte *buf, int buflen, bool for_fdarray); |
112 | | |
113 | | static int |
114 | | pdfi_alloc_cff_font(pdf_context *ctx, pdf_font_cff ** font, uint32_t obj_num, bool for_fdarray); |
115 | | |
116 | | /* CALLBACKS */ |
117 | | static int |
118 | | pdfi_cff_glyph_data(gs_font_type1 *pfont, gs_glyph glyph, gs_glyph_data_t *pgd) |
119 | 182k | { |
120 | 182k | int code = 0; |
121 | 182k | pdf_font_cff *cfffont = (pdf_font_cff *) pfont->client_data; |
122 | 182k | pdf_context *ctx = (pdf_context *) cfffont->ctx; |
123 | 182k | pdf_name *glyphname = NULL; |
124 | 182k | pdf_string *charstring = NULL; |
125 | | |
126 | | /* Getting here with Encoding == NULL means it's a subfont from an FDArray |
127 | | so we index directly by gid |
128 | | */ |
129 | 182k | if (cfffont->Encoding == NULL) { |
130 | 0 | char indstring[33]; |
131 | 0 | int l = gs_snprintf(indstring, sizeof(indstring), "%u", (unsigned int)glyph); |
132 | |
|
133 | 0 | code = pdfi_name_alloc(ctx, (byte *) indstring, l, (pdf_obj **) &glyphname); |
134 | 0 | if (code >= 0) |
135 | 0 | pdfi_countup(glyphname); |
136 | 0 | } |
137 | 182k | else { |
138 | 182k | gs_const_string gname; |
139 | 182k | code = (*ctx->get_glyph_name)((gs_font *)pfont, glyph, &gname); |
140 | 182k | if (code >= 0) { |
141 | 182k | code = pdfi_name_alloc(ctx, (byte *) gname.data, gname.size, (pdf_obj **) &glyphname); |
142 | 182k | if (code >= 0) |
143 | 182k | pdfi_countup(glyphname); |
144 | 182k | } |
145 | 182k | } |
146 | 182k | if (code >= 0) { |
147 | 182k | code = pdfi_dict_get_by_key(ctx, cfffont->CharStrings, glyphname, (pdf_obj **) &charstring); |
148 | 182k | if (code < 0) { |
149 | 0 | code = pdfi_map_glyph_name_via_agl(cfffont->CharStrings, glyphname, &charstring); |
150 | 0 | } |
151 | 182k | if (code >= 0) |
152 | 182k | gs_glyph_data_from_bytes(pgd, charstring->data, 0, charstring->length, NULL); |
153 | 182k | } |
154 | | |
155 | 182k | pdfi_countdown(glyphname); |
156 | 182k | pdfi_countdown(charstring); |
157 | | |
158 | 182k | return code; |
159 | 182k | } |
160 | | |
161 | | static int |
162 | | pdfi_cff_subr_data(gs_font_type1 *pfont, int index, bool global, gs_glyph_data_t *pgd) |
163 | 156k | { |
164 | 156k | int code = 0; |
165 | 156k | pdf_font_cff *cfffont = (pdf_font_cff *) pfont->client_data; |
166 | | |
167 | 156k | if ((global &&index >= cfffont->NumGlobalSubrs)||(!global &&index >= cfffont->NumSubrs)) { |
168 | 2.51k | code = gs_note_error(gs_error_rangecheck); |
169 | 2.51k | } |
170 | 154k | else { |
171 | 154k | pdf_string *subrstring; |
172 | 154k | pdf_array *s = global ? cfffont->GlobalSubrs : cfffont->Subrs; |
173 | | |
174 | 154k | code = pdfi_array_get(cfffont->ctx, s, (uint64_t) index, (pdf_obj **) &subrstring); |
175 | 154k | if (code >= 0) { |
176 | 153k | gs_glyph_data_from_bytes(pgd, subrstring->data, 0, subrstring->length, NULL); |
177 | 153k | pdfi_countdown(subrstring); |
178 | 153k | } |
179 | 154k | } |
180 | 156k | return code; |
181 | 156k | } |
182 | | |
183 | | static int |
184 | | pdfi_cff_seac_data(gs_font_type1 *pfont, int ccode, gs_glyph *pglyph, gs_const_string *gstr, gs_glyph_data_t *pgd) |
185 | 1.00k | { |
186 | 1.00k | int code = 0; |
187 | 1.00k | pdf_font_cff *cfffont = (pdf_font_cff *) pfont->client_data; |
188 | 1.00k | pdf_context *ctx = (pdf_context *) cfffont->ctx; |
189 | 1.00k | gs_glyph glyph = gs_c_known_encode((gs_char)ccode, ENCODING_INDEX_STANDARD); |
190 | | |
191 | 1.00k | if (glyph == GS_NO_GLYPH) |
192 | 384 | return_error(gs_error_rangecheck); |
193 | | |
194 | 620 | code = gs_c_glyph_name(glyph, gstr); |
195 | | |
196 | 620 | if (code >= 0) { |
197 | 620 | unsigned int nindex; |
198 | 620 | code = (*ctx->get_glyph_index)((gs_font *)pfont, (byte *)gstr->data, gstr->size, &nindex); |
199 | 620 | if (pglyph != NULL) |
200 | 618 | *pglyph = (gs_glyph)nindex; |
201 | 620 | } |
202 | | |
203 | 620 | if (code >= 0) { |
204 | 620 | pdf_name *glyphname = NULL; |
205 | 620 | pdf_string *charstring = NULL; |
206 | 620 | code = pdfi_name_alloc(ctx, (byte *) gstr->data, gstr->size, (pdf_obj **) &glyphname); |
207 | 620 | if (code >= 0) { |
208 | 620 | pdfi_countup(glyphname); |
209 | 620 | code = pdfi_dict_get_by_key(ctx, cfffont->CharStrings, glyphname, (pdf_obj **)&charstring); |
210 | 620 | pdfi_countdown(glyphname); |
211 | 620 | if (code >= 0) { |
212 | 620 | if (pgd != NULL) { |
213 | 2 | gs_glyph_data_from_bytes(pgd, charstring->data, 0, charstring->length, NULL); |
214 | 2 | } |
215 | 620 | pdfi_countdown(charstring); |
216 | 620 | } |
217 | 620 | } |
218 | 620 | } |
219 | | |
220 | 620 | return code; |
221 | 1.00k | } |
222 | | |
223 | | /* push/pop are null ops here */ |
224 | | static int |
225 | | pdfi_cff_push(void *callback_data, const fixed *pf, int count) |
226 | 0 | { |
227 | 0 | (void)callback_data; |
228 | 0 | (void)pf; |
229 | 0 | (void)count; |
230 | 0 | return 0; |
231 | 0 | } |
232 | | static int |
233 | | pdfi_cff_pop(void *callback_data, fixed *pf) |
234 | 0 | { |
235 | 0 | (void)callback_data; |
236 | 0 | (void)pf; |
237 | 0 | return 0; |
238 | 0 | } |
239 | | |
240 | | static int |
241 | | pdfi_cff_enumerate_glyph(gs_font *pfont, int *pindex, |
242 | | gs_glyph_space_t glyph_space, gs_glyph *pglyph) |
243 | 112k | { |
244 | 112k | int code, j; |
245 | 112k | pdf_name *key = NULL; |
246 | 112k | uint64_t i = (uint64_t) *pindex; |
247 | 112k | pdf_dict *cstrings; |
248 | 112k | pdf_font *pdffont = (pdf_font *) pfont->client_data; |
249 | 112k | pdf_context *ctx = (pdf_context *) pdffont->ctx; |
250 | | |
251 | 112k | (void)glyph_space; |
252 | | |
253 | | /* Slightly naff: if build_char is NULL, this is an FDArray subfont */ |
254 | 112k | if (pfont->procs.build_char == NULL) { |
255 | 123 | *pindex = 0; |
256 | 123 | *pglyph = GS_NO_GLYPH; |
257 | 123 | return 0; |
258 | 123 | } |
259 | 112k | else if (pdffont->pdfi_font_type == e_pdf_cidfont_type0) { |
260 | 72 | pdf_cidfont_type0 *cffcidfont = (pdf_cidfont_type0 *) pdffont; |
261 | 72 | cstrings = cffcidfont->CharStrings; |
262 | 72 | } |
263 | 111k | else { |
264 | 111k | pdf_font_cff *cfffont = (pdf_font_cff *) pdffont; |
265 | | |
266 | 111k | cstrings = cfffont->CharStrings; |
267 | 111k | } |
268 | 112k | if (*pindex <= 0) |
269 | 1.60k | code = pdfi_dict_key_first(pdffont->ctx, cstrings, (pdf_obj **) &key, &i); |
270 | 110k | else |
271 | 110k | code = pdfi_dict_key_next(pdffont->ctx, cstrings, (pdf_obj **) &key, &i); |
272 | 112k | if (code < 0) { |
273 | 681 | i = 0; |
274 | 681 | code = gs_note_error(gs_error_undefined); |
275 | 681 | } |
276 | | /* If Encoding == NULL, it's an FDArray subfont */ |
277 | 111k | else if (pdffont->pdfi_font_type != e_pdf_cidfont_type0 && pdffont->Encoding != NULL) { |
278 | 111k | unsigned int nindex; |
279 | 111k | code = (*ctx->get_glyph_index)(pfont, key->data, key->length, &nindex); |
280 | 111k | if (code < 0) { |
281 | 8 | code = (*ctx->get_glyph_index)(pfont, (byte *)".notdef", 7, &nindex); |
282 | 8 | if (code < 0) |
283 | 0 | *pglyph = GS_NO_GLYPH; |
284 | 8 | else |
285 | 8 | *pglyph = (gs_glyph)nindex; |
286 | 8 | } |
287 | 111k | else |
288 | 111k | *pglyph = (gs_glyph)nindex; |
289 | 111k | } |
290 | 69 | else { |
291 | 69 | char kbuf[32]; |
292 | 69 | int l; |
293 | 69 | unsigned int val; |
294 | | /* If this font started life as a CFF font that we've force to |
295 | | act like a CIDFont, we can end up with a ".notdef" glyph name |
296 | | */ |
297 | 69 | if (key->length == 7 && memcmp(key->data, ".notdef", 7) == 0) { |
298 | 0 | val = 0; |
299 | 0 | l = 1; |
300 | 0 | } |
301 | 69 | else { |
302 | 69 | memcpy(kbuf, key->data, key->length); |
303 | 69 | kbuf[key->length] = 0; |
304 | | |
305 | 69 | l = sscanf(kbuf, "%ud", &val); |
306 | 69 | } |
307 | 69 | if (l > 0) { |
308 | 69 | pdf_cidfont_type0 *cffcidfont = (pdf_cidfont_type0 *) pdffont; |
309 | 69 | if (cffcidfont->cidtogidmap != NULL && cffcidfont->cidtogidmap->length > 0) { |
310 | 0 | for (j = (cffcidfont->cidtogidmap->length >> 1) - 1; j >= 0; j--) { |
311 | 0 | if (val == (cffcidfont->cidtogidmap->data[j << 1] << 8 | cffcidfont->cidtogidmap->data[(j << 1) + 1])) { |
312 | 0 | val = j; |
313 | 0 | break; |
314 | 0 | } |
315 | 0 | } |
316 | 0 | } |
317 | 69 | *pglyph = (gs_glyph) (val) + GS_MIN_CID_GLYPH; |
318 | 69 | } |
319 | 69 | } |
320 | 112k | *pindex = (int)i; |
321 | 112k | pdfi_countdown(key); |
322 | 112k | return code; |
323 | 112k | } |
324 | | |
325 | | /* This *should* only get called for SEAC lookups, which have to come from StandardEncoding |
326 | | so just try to lookup the string in the standard encodings |
327 | | */ |
328 | | int |
329 | | pdfi_cff_global_glyph_code(const gs_font *pfont, gs_const_string *gstr, gs_glyph *pglyph) |
330 | 7 | { |
331 | 7 | *pglyph = gs_c_name_glyph(gstr->data, gstr->size); |
332 | 7 | return 0; |
333 | 7 | } |
334 | | |
335 | | static int |
336 | | pdfi_cff_glyph_outline(gs_font *pfont, int WMode, gs_glyph glyph, |
337 | | const gs_matrix *pmat, gx_path *ppath, double sbw[4]) |
338 | 5.79k | { |
339 | 5.79k | gs_glyph_data_t gd; |
340 | 5.79k | gs_glyph_data_t *pgd = &gd; |
341 | 5.79k | gs_font_type1 *pfont1; |
342 | 5.79k | int code; |
343 | | |
344 | 5.79k | if (pfont->FontType == ft_CID_encrypted) { |
345 | 3.69k | gs_font_cid0 *pfcid0 = (gs_font_cid0 *) pfont; |
346 | 3.69k | int fididx = 0; |
347 | | |
348 | 3.69k | code = (*pfcid0->cidata.glyph_data) ((gs_font_base *) pfont, glyph, pgd, &fididx); |
349 | 3.69k | if (fididx < pfcid0->cidata.FDArray_size) |
350 | 3.69k | pfont1 = pfcid0->cidata.FDArray[fididx]; |
351 | 0 | else |
352 | 0 | code = gs_note_error(gs_error_invalidaccess); |
353 | 3.69k | } |
354 | 2.10k | else { |
355 | 2.10k | pfont1 = (gs_font_type1 *) pfont; |
356 | 2.10k | code = (*pfont1->data.procs.glyph_data) ((gs_font_type1 *) pfont, glyph, pgd); |
357 | 2.10k | } |
358 | | |
359 | 5.79k | if (code >= 0) { |
360 | 5.72k | gs_type1_state cis = { 0 }; |
361 | 5.72k | gs_type1_state *pcis = &cis; |
362 | 5.72k | gs_gstate gs; |
363 | 5.72k | int value; |
364 | | |
365 | 5.72k | if (pmat) |
366 | 2.88k | gs_matrix_fixed_from_matrix(&gs.ctm, pmat); |
367 | 2.84k | else { |
368 | 2.84k | gs_matrix imat; |
369 | | |
370 | 2.84k | gs_make_identity(&imat); |
371 | 2.84k | gs_matrix_fixed_from_matrix(&gs.ctm, &imat); |
372 | 2.84k | } |
373 | 5.72k | gs.flatness = 0; |
374 | 5.72k | code = gs_type1_interp_init(pcis, &gs, ppath, NULL, NULL, true, 0, pfont1); |
375 | 5.72k | if (code < 0) |
376 | 0 | return code; |
377 | | |
378 | 5.72k | pcis->no_grid_fitting = true; |
379 | 5.72k | gs_type1_set_callback_data(pcis, NULL); |
380 | | /* Continue interpreting. */ |
381 | 11.3k | icont: |
382 | 11.3k | code = pfont1->data.interpret(pcis, pgd, &value); |
383 | 11.3k | switch (code) { |
384 | 5.60k | case 0: /* all done */ |
385 | | /* falls through */ |
386 | 5.72k | default: /* code < 0, error */ |
387 | 5.72k | return code; |
388 | 0 | case type1_result_callothersubr: /* unknown OtherSubr */ |
389 | 0 | return_error(gs_error_rangecheck); /* can't handle it */ |
390 | 5.66k | case type1_result_sbw: /* [h]sbw, just continue */ |
391 | 5.66k | type1_cis_get_metrics(pcis, sbw); |
392 | 5.66k | pgd = 0; |
393 | 5.66k | goto icont; |
394 | 11.3k | } |
395 | 11.3k | } |
396 | 66 | return code; |
397 | 5.79k | } |
398 | | static int |
399 | | pdfi_cff_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat, int members, gs_glyph_info_t *info) |
400 | 153k | { |
401 | 153k | if ((members & GLYPH_INFO_OUTLINE_WIDTHS) == 0) |
402 | 151k | return gs_type1_glyph_info(font, glyph, pmat, members, info); |
403 | | |
404 | 1.98k | return gs_default_glyph_info(font, glyph, pmat, members, info); |
405 | 153k | } |
406 | | |
407 | | static int |
408 | | pdfi_cff_fdarray_glyph_data(gs_font_type1 *pfont, gs_glyph glyph, gs_glyph_data_t *pgd) |
409 | 0 | { |
410 | 0 | return_error(gs_error_invalidfont); |
411 | 0 | } |
412 | | |
413 | | static int |
414 | | pdfi_cff_fdarray_seac_data(gs_font_type1 *pfont, int ccode, |
415 | | gs_glyph *pglyph, gs_const_string *gstr, gs_glyph_data_t *pgd) |
416 | 0 | { |
417 | 0 | return_error(gs_error_invalidfont); |
418 | 0 | } |
419 | | |
420 | | /* Note that pgd may be NULL - so only retrieve the fidx */ |
421 | | static int |
422 | | pdfi_cff_cid_glyph_data(gs_font_base *pbfont, gs_glyph glyph, gs_glyph_data_t *pgd, int *pfidx) |
423 | 48.6k | { |
424 | 48.6k | int code = 0; |
425 | 48.6k | pdf_cidfont_type0 *pdffont9 = (pdf_cidfont_type0 *) pbfont->client_data; |
426 | 48.6k | gs_font_cid0 *gscidfont = (gs_font_cid0 *) pbfont; |
427 | 48.6k | pdf_name *glyphname = NULL; |
428 | 48.6k | pdf_string *charstring = NULL; |
429 | 48.6k | char nbuf[64]; |
430 | 48.6k | uint32_t l; |
431 | 48.6k | gs_glyph gid; |
432 | | |
433 | 48.6k | *pfidx = 0; |
434 | | |
435 | 48.6k | if (glyph < GS_MIN_CID_GLYPH) |
436 | 12.2k | gid = glyph; |
437 | 36.4k | else |
438 | 36.4k | gid = glyph - GS_MIN_CID_GLYPH; |
439 | | |
440 | 48.6k | if (pdffont9->cidtogidmap != NULL && pdffont9->cidtogidmap->length > (gid << 1) + 1) { |
441 | 174 | gid = pdffont9->cidtogidmap->data[gid << 1] << 8 | pdffont9->cidtogidmap->data[(gid << 1) + 1]; |
442 | 174 | } |
443 | | |
444 | 48.6k | l = gs_snprintf(nbuf, sizeof(nbuf), "%" PRId64, gid); |
445 | | |
446 | 48.6k | code = pdfi_name_alloc(pdffont9->ctx, (byte *) nbuf, l, (pdf_obj **) &glyphname); |
447 | 48.6k | if (code >= 0) { |
448 | 48.6k | pdfi_countup(glyphname); |
449 | 48.6k | code = pdfi_dict_get_by_key(pdffont9->ctx, pdffont9->CharStrings, glyphname, (pdf_obj **) &charstring); |
450 | 48.6k | if (code >= 0 && charstring->length >= gscidfont->cidata.FDBytes) { |
451 | 37.6k | if (gscidfont->cidata.FDBytes != 0) { |
452 | 32.8k | if ((int)charstring->data[0] > gscidfont->cidata.FDArray_size) |
453 | 36 | code = gs_note_error(gs_error_invalidfont); |
454 | 32.8k | else |
455 | 32.8k | *pfidx = (int)charstring->data[0]; |
456 | 32.8k | } |
457 | | |
458 | 37.6k | if (code >= 0 && pgd && ((int64_t)charstring->length - (int64_t)gscidfont->cidata.FDBytes) >= 0) |
459 | 13.3k | gs_glyph_data_from_bytes(pgd, charstring->data + gscidfont->cidata.FDBytes, 0, charstring->length - gscidfont->cidata.FDBytes, NULL); |
460 | 37.6k | } |
461 | 48.6k | } |
462 | 48.6k | pdfi_countdown(charstring); |
463 | 48.6k | pdfi_countdown(glyphname); |
464 | | |
465 | 48.6k | return code; |
466 | 48.6k | } |
467 | | |
468 | | |
469 | | static int |
470 | | pdfi_cff_cidfont_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat, |
471 | | int members, gs_glyph_info_t *info) |
472 | 3.69k | { |
473 | 3.69k | int code; |
474 | 3.69k | gs_font_cid0 *pcidfont = (gs_font_cid0 *)font; |
475 | 3.69k | pdf_cidfont_type0 *pdffont9 = (pdf_cidfont_type0 *)font->client_data; |
476 | 3.69k | code = (*pdffont9->orig_glyph_info)(font, glyph, pmat, members, info); |
477 | 3.69k | if (code < 0) |
478 | 76 | return code; |
479 | | |
480 | 3.61k | if ((members & GLYPH_INFO_WIDTHS) != 0 |
481 | 3.61k | && glyph > GS_MIN_CID_GLYPH |
482 | 3.61k | && glyph < GS_MIN_GLYPH_INDEX) { |
483 | 2.94k | double widths[6] = {0}; |
484 | 2.94k | int fidx; |
485 | 2.94k | gs_matrix imat; |
486 | 2.94k | gs_matrix mat1 = font->FontMatrix; |
487 | 2.94k | gs_glyph g = glyph - GS_MIN_CID_GLYPH; |
488 | | |
489 | 2.94k | code = (*pcidfont->cidata.glyph_data) ((gs_font_base *)font, g + GS_MIN_CID_GLYPH, NULL, &fidx); |
490 | 2.94k | if (code < 0) |
491 | 0 | return code; |
492 | 2.94k | if (fidx < pcidfont->cidata.FDArray_size) { |
493 | 2.94k | gs_font_type1 *pfdfont = pcidfont->cidata.FDArray[fidx]; |
494 | | /* The following cannot fail - if the matrix multiplication didn't work |
495 | | we'd have errored out at a higher level |
496 | | */ |
497 | 2.94k | (void)gs_matrix_multiply(&font->FontMatrix, &pfdfont->FontMatrix, &mat1); |
498 | 2.94k | } |
499 | 2.94k | code = gs_matrix_invert(&mat1, &imat); |
500 | 2.94k | if (code < 0) |
501 | 0 | return code; /* By this stage, this should be impossible */ |
502 | 2.94k | if (pmat) { |
503 | 901 | gs_matrix_multiply(&imat, pmat, &mat1); |
504 | 901 | } |
505 | 2.04k | else { |
506 | 2.04k | mat1 = imat; |
507 | 2.04k | } |
508 | | |
509 | 2.94k | code = pdfi_get_cidfont_glyph_metrics(font, g, widths, true); |
510 | 2.94k | if (code >= 0) { |
511 | 2.94k | code = gs_point_transform(widths[GLYPH_W0_WIDTH_INDEX] / 1000.0, widths[GLYPH_W0_HEIGHT_INDEX] / 1000.0, &mat1, &info->width[0]); |
512 | 2.94k | if (code < 0) |
513 | 0 | return code; |
514 | 2.94k | info->members |= GLYPH_INFO_WIDTH0; |
515 | | |
516 | 2.94k | if ((members & GLYPH_INFO_WIDTH1) != 0 && (widths[GLYPH_W1_WIDTH_INDEX] != 0 || widths[GLYPH_W1_HEIGHT_INDEX] != 0)) { |
517 | 306 | code = gs_point_transform(widths[GLYPH_W1_WIDTH_INDEX] / 1000.0, widths[GLYPH_W1_HEIGHT_INDEX] / 1000.0, &mat1, &info->width[1]); |
518 | 306 | info->members |= GLYPH_INFO_WIDTH1; |
519 | 306 | } |
520 | 2.94k | if ((members & GLYPH_INFO_VVECTOR1) != 0) { |
521 | 306 | code = gs_point_transform(widths[GLYPH_W1_V_X_INDEX] / 1000.0, widths[GLYPH_W1_V_Y_INDEX] / 1000.0, &mat1, &info->v); |
522 | 306 | info->members |= GLYPH_INFO_VVECTOR1; |
523 | 306 | } |
524 | 2.94k | } |
525 | 2.94k | } |
526 | 3.61k | return code; |
527 | 3.61k | } |
528 | | |
529 | | /* END CALLBACKS */ |
530 | | |
531 | | #if 0 /* not currently used */ |
532 | | static inline int |
533 | | s16(const byte *p) |
534 | | { |
535 | | return (signed short)((p[0] << 8) | p[1]); |
536 | | } |
537 | | #endif /* not currently used */ |
538 | | |
539 | | static inline int |
540 | | u16(const byte *p) |
541 | 23.5M | { |
542 | 23.5M | return (p[0] << 8) | p[1]; |
543 | 23.5M | } |
544 | | |
545 | | static inline int |
546 | | u24(const byte *p) |
547 | 2.38k | { |
548 | 2.38k | return (p[0] << 16) | (p[1] << 8) | p[2]; |
549 | 2.38k | } |
550 | | |
551 | | static inline int |
552 | | u32(const byte *p) |
553 | 3.08k | { |
554 | 3.08k | return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; |
555 | 3.08k | } |
556 | | |
557 | | |
558 | | static int |
559 | | subrbias(int count) |
560 | 1.57k | { |
561 | 1.57k | return count < 1240 ? 107 : count < 33900 ? 1131 : 32768; |
562 | 1.57k | } |
563 | | |
564 | | static int |
565 | | uofs(const byte *p, int offsize) |
566 | 1.34M | { |
567 | 1.34M | if (offsize == 1) |
568 | 137k | return p[0]; |
569 | 1.20M | if (offsize == 2) |
570 | 1.19M | return u16(p); |
571 | 5.15k | if (offsize == 3) |
572 | 2.38k | return u24(p); |
573 | 2.77k | if (offsize == 4) |
574 | 2.77k | return u32(p); |
575 | 0 | return 0; |
576 | 2.77k | } |
577 | | |
578 | | static int |
579 | | iso_adobe_charset_proc(const byte *p, const byte *pe, unsigned i) |
580 | 2.61k | { |
581 | 2.61k | if (i < 228) |
582 | 2.61k | return i + 1; |
583 | 0 | else |
584 | 0 | return_error(gs_error_rangecheck); |
585 | 2.61k | } |
586 | | |
587 | | static int |
588 | | expert_charset_proc(const byte *p, const byte *pe, unsigned i) |
589 | 0 | { |
590 | 0 | if (i < gs_c_known_encoding_lengths[6]) |
591 | 0 | return gs_c_known_encodings[6][i]; |
592 | | |
593 | 0 | return_error(gs_error_rangecheck); |
594 | 0 | } |
595 | | |
596 | | static int |
597 | | expert_subset_charset_proc(const byte *p, const byte *pe, unsigned int i) |
598 | 0 | { |
599 | | #if 0 |
600 | | if (i < sizeof(expert_subset_charset) / sizeof(*expert_subset_charset)) |
601 | | return expert_subset_charset[i]; |
602 | | #endif |
603 | 0 | return_error(gs_error_rangecheck); |
604 | 0 | } |
605 | | |
606 | | static int |
607 | | format0_charset_proc(const byte *p, const byte *pe, unsigned int i) |
608 | 37.6k | { |
609 | 37.6k | if (p + 2 * i > pe) |
610 | 0 | return gs_error_rangecheck; |
611 | | |
612 | 37.6k | return u16(p + 2 * i); |
613 | 37.6k | } |
614 | | |
615 | | static int |
616 | | format1_charset_proc(const byte *p, const byte *pe, unsigned int i) |
617 | 99.6k | { |
618 | 99.6k | int code = gs_error_rangecheck; |
619 | 99.6k | unsigned int cid = 0; |
620 | | |
621 | 2.80M | while (p < pe - 3) { |
622 | 2.80M | unsigned int first, count; |
623 | | |
624 | 2.80M | first = (unsigned int)u16(p); |
625 | 2.80M | count = (unsigned int)p[2] + 1; |
626 | | |
627 | 2.80M | if (i < cid + count) { |
628 | 99.6k | code = first + i - cid; |
629 | 99.6k | break; |
630 | 99.6k | } |
631 | 2.70M | p += 3; |
632 | 2.70M | cid += count; |
633 | 2.70M | } |
634 | 99.6k | return code; |
635 | 99.6k | } |
636 | | |
637 | | static int |
638 | | format2_charset_proc(const byte *p, const byte *pe, unsigned int i) |
639 | 131k | { |
640 | 131k | int code = gs_error_rangecheck; |
641 | 131k | unsigned int cid = 0; |
642 | | |
643 | 131k | while (p < pe - 4) { |
644 | 131k | unsigned int first, count; |
645 | | |
646 | 131k | first = u16(p); |
647 | 131k | count = u16(p + 2) + 1; |
648 | | |
649 | 131k | if (i < cid + count) { |
650 | 131k | code = first + i - cid; |
651 | 131k | break; |
652 | 131k | } |
653 | 0 | p += 4; |
654 | 0 | cid += count; |
655 | 0 | } |
656 | 131k | return code; |
657 | 131k | } |
658 | | |
659 | | static int |
660 | | format0_fdselect_proc(const byte *p, const byte *pe, unsigned int i) |
661 | 747 | { |
662 | 747 | return (int)(*(p + i)); |
663 | 747 | } |
664 | | |
665 | | static int |
666 | | format3_fdselect_proc(const byte *p, const byte *pe, unsigned int i) |
667 | 132k | { |
668 | 132k | unsigned int n_ranges; |
669 | | |
670 | 132k | n_ranges = u16(p); |
671 | 132k | p += 2; |
672 | | |
673 | 9.33M | while (n_ranges-- && p + 5 <= pe) { |
674 | 9.33M | unsigned int first, last; |
675 | | |
676 | 9.33M | first = u16(p); |
677 | 9.33M | last = u16(p + 3); |
678 | | |
679 | 9.33M | if (i >= first && i < last) { |
680 | 132k | return (int)(*(p + 2)); |
681 | 132k | } |
682 | 9.20M | p += 3; |
683 | 9.20M | } |
684 | 132k | return_error(gs_error_rangecheck); |
685 | 132k | } |
686 | | |
687 | | |
688 | | static byte * |
689 | | pdfi_read_cff_real(byte *p, byte *e, float *val) |
690 | 3.53k | { |
691 | 3.53k | char buf[64]; |
692 | 3.53k | char *txt = buf; |
693 | | |
694 | | /* b0 was 30 */ |
695 | | |
696 | 14.0k | while (txt < buf + (sizeof buf) - 3 && p < e) { |
697 | 14.0k | int b, n; |
698 | | |
699 | 14.0k | b = *p++; |
700 | | |
701 | 14.0k | n = (b >> 4) &0xf; |
702 | 14.0k | if (n < 0xA) { |
703 | 9.86k | *txt++ = n + '0'; |
704 | 9.86k | } |
705 | 4.15k | else if (n == 0xA) { |
706 | 2.02k | *txt++ = '.'; |
707 | 2.02k | } |
708 | 2.12k | else if (n == 0xB) { |
709 | 21 | *txt++ = 'E'; |
710 | 21 | } |
711 | 2.10k | else if (n == 0xC) { |
712 | 49 | *txt++ = 'E'; |
713 | 49 | *txt++ = '-'; |
714 | 49 | } |
715 | 2.05k | else if (n == 0xE) { |
716 | 213 | *txt++ = '-'; |
717 | 213 | } |
718 | 1.84k | else if (n == 0xF) { |
719 | 1.83k | break; |
720 | 1.83k | } |
721 | | |
722 | 12.1k | n = b &0xf; |
723 | 12.1k | if (n < 0xA) { |
724 | 9.20k | *txt++ = n + '0'; |
725 | 9.20k | } |
726 | 2.97k | else if (n == 0xA) { |
727 | 1.05k | *txt++ = '.'; |
728 | 1.05k | } |
729 | 1.92k | else if (n == 0xB) { |
730 | 54 | *txt++ = 'E'; |
731 | 54 | } |
732 | 1.86k | else if (n == 0xC) { |
733 | 51 | *txt++ = 'E'; |
734 | 51 | *txt++ = '-'; |
735 | 51 | } |
736 | 1.81k | else if (n == 0xE) { |
737 | 74 | *txt++ = '-'; |
738 | 74 | } |
739 | 1.74k | else if (n == 0xF) { |
740 | 1.68k | break; |
741 | 1.68k | } |
742 | 12.1k | } |
743 | | |
744 | 3.53k | *txt = 0; |
745 | | |
746 | 3.53k | *val = atof(buf); |
747 | | |
748 | 3.53k | return p; |
749 | 3.53k | } |
750 | | |
751 | | static byte * |
752 | | pdfi_read_cff_integer(byte *p, byte *e, int b0, int *val) |
753 | 94.9k | { |
754 | 94.9k | int b1, b2, b3, b4; |
755 | | |
756 | 94.9k | if (b0 == 28) { |
757 | 5.75k | if (p + 2 > e) { |
758 | 2 | gs_throw(-1, "corrupt dictionary (integer)"); |
759 | 2 | return 0; |
760 | 2 | } |
761 | 5.75k | b1 = *p++; |
762 | 5.75k | b2 = *p++; |
763 | 5.75k | *val = (b1 << 8) | b2; |
764 | 5.75k | } |
765 | | |
766 | 89.1k | else if (b0 == 29) { |
767 | 1.86k | if (p + 4 > e) { |
768 | 2 | gs_throw(-1, "corrupt dictionary (integer)"); |
769 | 2 | return 0; |
770 | 2 | } |
771 | 1.85k | b1 = *p++; |
772 | 1.85k | b2 = *p++; |
773 | 1.85k | b3 = *p++; |
774 | 1.85k | b4 = *p++; |
775 | 1.85k | *val = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; |
776 | 1.85k | } |
777 | | |
778 | 87.3k | else if (b0 < 247) { |
779 | 43.3k | *val = b0 - 139; |
780 | 43.3k | } |
781 | | |
782 | 43.9k | else if (b0 < 251) { |
783 | 34.3k | if (p + 1 > e) { |
784 | 31 | gs_throw(-1, "corrupt dictionary (integer)"); |
785 | 31 | return 0; |
786 | 31 | } |
787 | 34.3k | b1 = *p++; |
788 | 34.3k | *val = (b0 - 247) * 256 + b1 + 108; |
789 | 34.3k | } |
790 | | |
791 | 9.54k | else { |
792 | 9.54k | if (p + 1 > e) { |
793 | 3 | gs_throw(-1, "corrupt dictionary (integer)"); |
794 | 3 | return 0; |
795 | 3 | } |
796 | 9.53k | b1 = *p++; |
797 | 9.53k | *val = -(b0 - 251) * 256 - b1 - 108; |
798 | 9.53k | } |
799 | | |
800 | 94.8k | return p; |
801 | 94.9k | } |
802 | | |
803 | 145k | #define PDFI_CFF_STACK_SIZE 48 |
804 | | |
805 | | static int |
806 | | pdfi_read_cff_dict(byte *p, byte *e, pdfi_gs_cff_font_priv *ptpriv, cff_font_offsets *offsets, bool topdict) |
807 | 7.08k | { |
808 | 7.08k | pdfi_cff_font_priv *font = &ptpriv->pdfcffpriv; |
809 | 7.08k | struct |
810 | 7.08k | { |
811 | 7.08k | int ival; |
812 | 7.08k | float fval; |
813 | 7.08k | } args[PDFI_CFF_STACK_SIZE]; |
814 | 7.08k | int offset; |
815 | 7.08k | int b0, n; |
816 | 7.08k | double f; |
817 | 7.08k | int i; |
818 | 7.08k | int code = 0; |
819 | 7.08k | bool do_priv = false; |
820 | | |
821 | 7.08k | memset(args, 0x00, sizeof(args)); |
822 | | |
823 | 7.08k | offset = p - font->cffdata; |
824 | | |
825 | 7.08k | n = 0; |
826 | 153k | while (p < e && code >= 0) { |
827 | 146k | b0 = *p; |
828 | 146k | p++; |
829 | | |
830 | 146k | switch (b0) { |
831 | 25 | case 22: |
832 | 32 | case 23: |
833 | 66 | case 24: |
834 | 96 | case 25: |
835 | 151 | case 26: |
836 | 203 | case 27: |
837 | 270 | case 31: |
838 | 343 | case 255: |
839 | 343 | continue; |
840 | 145k | default: |
841 | 145k | break; |
842 | 146k | } |
843 | | |
844 | 145k | if (b0 < 22) { |
845 | 47.4k | if (b0 == 12) { |
846 | 10.8k | if (p + 1 > e) { |
847 | 4 | return gs_throw(-1, "corrupt dictionary (operator)"); |
848 | 4 | } |
849 | 10.8k | b0 = 0x100 | *p++; |
850 | 10.8k | } |
851 | 47.4k | switch (b0) { |
852 | 421 | case 13: /* UniqueID */ |
853 | 421 | break; |
854 | | |
855 | 524 | case 14: |
856 | 524 | break; /* XUID */ |
857 | | |
858 | | /* some CFF file offsets */ |
859 | 3.11k | case 15: |
860 | 3.11k | { |
861 | 3.11k | if (args[0].ival < 0) { |
862 | 13 | code = gs_note_error(gs_error_invalidfont); |
863 | 13 | break; |
864 | 13 | } |
865 | 3.09k | offsets->charset_off = args[0].ival; |
866 | 3.09k | break; |
867 | 3.11k | } |
868 | 1.58k | case 16: |
869 | 1.58k | { |
870 | 1.58k | if (args[0].ival < 0) { |
871 | 1 | code = gs_note_error(gs_error_invalidfont); |
872 | 1 | break; |
873 | 1 | } |
874 | 1.58k | offsets->encoding_off = args[0].ival; |
875 | 1.58k | break; |
876 | 1.58k | } |
877 | 3.15k | case 17: |
878 | 3.15k | { |
879 | 3.15k | if (args[0].ival < 0) { |
880 | 1 | code = gs_note_error(gs_error_invalidfont); |
881 | 1 | break; |
882 | 1 | } |
883 | 3.14k | font->charstrings = font->cffdata + args[0].ival; |
884 | 3.14k | break; |
885 | 3.15k | } |
886 | | |
887 | 3.30k | case 18: |
888 | 3.30k | { |
889 | 3.30k | offsets->private_size = args[0].ival; |
890 | 3.30k | if (args[1].ival < 0) { |
891 | 5 | code = gs_note_error(gs_error_invalidfont); |
892 | 5 | break; |
893 | 5 | } |
894 | 3.30k | offsets->private_off = args[1].ival; |
895 | | /* Catch a broken font with a self referencing Private dict */ |
896 | 3.30k | if (topdict == true) |
897 | 3.29k | do_priv = offsets->private_size > 0 ? true : false; |
898 | 8 | else { |
899 | 8 | do_priv = false; |
900 | 8 | code = gs_error_invalidfont; |
901 | 8 | break; |
902 | 8 | } |
903 | 3.29k | break; |
904 | 3.30k | } |
905 | | |
906 | 3.29k | case 19: |
907 | 238 | { |
908 | 238 | if (args[0].ival < 0) { |
909 | 10 | code = gs_note_error(gs_error_invalidfont); |
910 | 10 | break; |
911 | 10 | } |
912 | 228 | font->subrs = font->cffdata + offset + args[0].ival; |
913 | 228 | break; |
914 | 238 | } |
915 | | |
916 | 439 | case 256 | 30: |
917 | 439 | { |
918 | 439 | code = pdfi_make_string_from_sid(font->ctx, (pdf_obj **) &font->registry, font, offsets, args[0].ival); |
919 | 439 | if (code < 0) |
920 | 1 | break; |
921 | 438 | code = pdfi_make_string_from_sid(font->ctx, (pdf_obj **) &font->ordering, font, offsets, args[1].ival); |
922 | 438 | if (code < 0) |
923 | 0 | break; |
924 | 438 | font->supplement = args[2].ival; |
925 | 438 | offsets->have_ros = true; |
926 | 438 | ptpriv->FontType = ft_CID_encrypted; |
927 | 438 | break; |
928 | 438 | } |
929 | | |
930 | 432 | case 256 | 34: |
931 | 432 | { |
932 | 432 | font->cidcount = args[0].ival; |
933 | 432 | break; |
934 | 438 | } |
935 | | |
936 | 40 | case 256 | 35: |
937 | 40 | { |
938 | 40 | font->uidbase = args[0].ival; |
939 | 40 | break; |
940 | 438 | } |
941 | | |
942 | 439 | case 256 | 36: |
943 | 439 | { |
944 | 439 | offsets->fdarray_off = args[0].ival; |
945 | 439 | break; |
946 | 438 | } |
947 | | |
948 | 434 | case 256 | 37: |
949 | 434 | { |
950 | 434 | offsets->fdselect_off = args[0].ival; |
951 | 434 | break; |
952 | 438 | } |
953 | | |
954 | 587 | case 256 | 38: |
955 | 587 | { |
956 | 587 | pdf_string *fnamestr = NULL; |
957 | | |
958 | 587 | code = pdfi_make_string_from_sid(font->ctx, (pdf_obj **) &fnamestr, font, offsets, args[0].ival); |
959 | 587 | if (code >= 0) { |
960 | 587 | int nlen = fnamestr->length > gs_font_name_max ? gs_font_name_max : fnamestr->length; |
961 | 587 | memcpy(ptpriv->font_name.chars, fnamestr->data, nlen); |
962 | 587 | memcpy(ptpriv->key_name.chars, fnamestr->data, nlen); |
963 | 587 | ptpriv->font_name.size = ptpriv->key_name.size = nlen; |
964 | 587 | pdfi_countdown(fnamestr); |
965 | 587 | } |
966 | 587 | break; |
967 | 438 | } |
968 | | |
969 | | /* Type1 stuff that need to be set for the ptpriv struct */ |
970 | | |
971 | 1 | case 256 | 6: |
972 | 1 | { |
973 | 1 | if (args[0].ival == 1) { |
974 | 0 | ptpriv->type1data.interpret = gs_type1_interpret; |
975 | 0 | ptpriv->type1data.lenIV = -1; /* FIXME */ |
976 | 0 | } |
977 | 1 | break; |
978 | 438 | } |
979 | | |
980 | 162 | case 256 | 7: |
981 | 162 | { |
982 | 162 | ptpriv->FontMatrix.xx = args[0].fval; |
983 | 162 | ptpriv->FontMatrix.xy = args[1].fval; |
984 | 162 | ptpriv->FontMatrix.yx = args[2].fval; |
985 | 162 | ptpriv->FontMatrix.yy = args[3].fval; |
986 | 162 | ptpriv->FontMatrix.tx = args[4].fval; |
987 | 162 | ptpriv->FontMatrix.ty = args[5].fval; |
988 | 162 | offsets->have_matrix = true; |
989 | 162 | break; |
990 | 438 | } |
991 | 3.30k | case 5: |
992 | 3.30k | { |
993 | 3.30k | ptpriv->FontBBox.p.x = args[0].fval; |
994 | 3.30k | ptpriv->FontBBox.p.y = args[1].fval; |
995 | 3.30k | ptpriv->FontBBox.q.x = args[2].fval; |
996 | 3.30k | ptpriv->FontBBox.q.y = args[3].fval; |
997 | 3.30k | break; |
998 | 438 | } |
999 | | |
1000 | 1.97k | case 20: |
1001 | 1.97k | { |
1002 | 1.97k | ptpriv->type1data.defaultWidthX = float2fixed(args[0].fval); |
1003 | 1.97k | break; |
1004 | 438 | } |
1005 | | |
1006 | 1.75k | case 21: |
1007 | 1.75k | { |
1008 | 1.75k | ptpriv->type1data.nominalWidthX = float2fixed(args[0].fval); |
1009 | 1.75k | break; |
1010 | 438 | } |
1011 | | |
1012 | 0 | case 256 | 19: |
1013 | 0 | { |
1014 | 0 | ptpriv->type1data.initialRandomSeed = args[0].ival; |
1015 | 0 | break; |
1016 | 438 | } |
1017 | | |
1018 | 2.64k | case 6: |
1019 | 2.64k | { |
1020 | 2.64k | if (n > max_BlueValues * 2) n = max_BlueValues * 2; |
1021 | 2.64k | ptpriv->type1data.BlueValues.count = n; |
1022 | 2.64k | ptpriv->type1data.BlueValues.values[0] = args[0].fval; |
1023 | 17.2k | for (i = 1; i < n; i++) { |
1024 | 14.6k | ptpriv->type1data.BlueValues.values[i] = ptpriv->type1data.BlueValues.values[i - 1] + args[i].fval; |
1025 | 14.6k | } |
1026 | 2.64k | break; |
1027 | 438 | } |
1028 | | |
1029 | 1.80k | case 7: |
1030 | 1.80k | { |
1031 | 1.80k | if (n > max_OtherBlues * 2) n = max_OtherBlues * 2; |
1032 | 1.80k | ptpriv->type1data.OtherBlues.count = n; |
1033 | 1.80k | ptpriv->type1data.OtherBlues.values[0] = args[0].fval; |
1034 | 7.66k | for (i = 1; i < n; i++) { |
1035 | 5.86k | ptpriv->type1data.OtherBlues.values[i] = ptpriv->type1data.OtherBlues.values[i - 1] + args[i].fval; |
1036 | 5.86k | } |
1037 | 1.80k | break; |
1038 | 438 | } |
1039 | | |
1040 | 789 | case 8: |
1041 | 789 | { |
1042 | 789 | if (n > max_FamilyBlues * 2) n = max_FamilyBlues * 2; |
1043 | 789 | ptpriv->type1data.FamilyBlues.count = n; |
1044 | 789 | ptpriv->type1data.FamilyBlues.values[0] = args[0].fval; |
1045 | 4.29k | for (i = 1; i < n; i++) { |
1046 | 3.50k | ptpriv->type1data.FamilyBlues.values[i] = ptpriv->type1data.FamilyBlues.values[i - 1] + args[i].fval; |
1047 | 3.50k | } |
1048 | 789 | break; |
1049 | 438 | } |
1050 | | |
1051 | 662 | case 9: |
1052 | 662 | { |
1053 | 662 | if (n > max_FamilyOtherBlues * 2) n = max_FamilyOtherBlues * 2; |
1054 | 662 | ptpriv->type1data.FamilyOtherBlues.count = n; |
1055 | 662 | ptpriv->type1data.FamilyOtherBlues.values[0] = args[0].fval; |
1056 | 3.39k | for (i = 1; i < n; i++) { |
1057 | 2.72k | ptpriv->type1data.FamilyOtherBlues.values[i] = ptpriv->type1data.FamilyOtherBlues.values[i - 1] + args[i].fval; |
1058 | 2.72k | } |
1059 | 662 | break; |
1060 | 438 | } |
1061 | | |
1062 | 1.96k | case 10: |
1063 | 1.96k | { |
1064 | 1.96k | ptpriv->type1data.StdHW.count = 1; |
1065 | 1.96k | ptpriv->type1data.StdHW.values[0] = args[0].fval; |
1066 | 1.96k | break; |
1067 | 438 | } |
1068 | | |
1069 | 2.01k | case 11: |
1070 | 2.01k | { |
1071 | 2.01k | ptpriv->type1data.StdVW.count = 1; |
1072 | 2.01k | ptpriv->type1data.StdVW.values[0] = args[0].fval; |
1073 | 2.01k | break; |
1074 | 438 | } |
1075 | | |
1076 | 700 | case 256 | 9: |
1077 | 700 | { |
1078 | 700 | ptpriv->type1data.BlueScale = args[0].fval; |
1079 | 700 | break; |
1080 | 438 | } |
1081 | | |
1082 | 82 | case 256 | 10: |
1083 | 82 | { |
1084 | 82 | ptpriv->type1data.BlueShift = args[0].fval; |
1085 | 82 | break; |
1086 | 438 | } |
1087 | | |
1088 | 112 | case 256 | 11: |
1089 | 112 | { |
1090 | 112 | ptpriv->type1data.BlueFuzz = (int)args[0].fval; |
1091 | 112 | break; |
1092 | 438 | } |
1093 | | |
1094 | 1.17k | case 256 | 12: |
1095 | 1.17k | { |
1096 | 1.17k | if (n > max_StemSnap) n = max_StemSnap; |
1097 | 1.17k | ptpriv->type1data.StemSnapH.count = n; |
1098 | 5.47k | for (f = 0, i = 0; i < n; f += args[i].fval, i++) |
1099 | 4.29k | ptpriv->type1data.StemSnapH.values[i] = f; |
1100 | 1.17k | break; |
1101 | 438 | } |
1102 | | |
1103 | 1.27k | case 256 | 13: |
1104 | 1.27k | { |
1105 | 1.27k | if (n > max_StemSnap) n = max_StemSnap; |
1106 | 1.27k | ptpriv->type1data.StemSnapV.count = n; |
1107 | 5.27k | for (f = 0, i = 0; i < n; f += args[i].fval, i++) |
1108 | 3.99k | ptpriv->type1data.StemSnapV.values[i] = f; |
1109 | 1.27k | break; |
1110 | 438 | } |
1111 | | |
1112 | 675 | case 256 | 14: |
1113 | 675 | { |
1114 | 675 | ptpriv->type1data.ForceBold = args[0].ival; |
1115 | 675 | break; |
1116 | 438 | } |
1117 | | |
1118 | 221 | case 256 | 17: |
1119 | 221 | { |
1120 | 221 | ptpriv->type1data.LanguageGroup = args[0].ival; |
1121 | 221 | break; |
1122 | 438 | } |
1123 | | |
1124 | 11 | case 256 | 18: |
1125 | 11 | { |
1126 | 11 | ptpriv->type1data.ExpansionFactor = args[0].fval; |
1127 | 11 | break; |
1128 | 438 | } |
1129 | 11.4k | default: |
1130 | 11.4k | break; |
1131 | 47.4k | } |
1132 | 47.4k | n = 0; |
1133 | 47.4k | } |
1134 | 98.4k | else { |
1135 | 98.4k | if (b0 == 30) { |
1136 | 3.53k | p = pdfi_read_cff_real(p, e, &args[n].fval); |
1137 | 3.53k | if (!p) { |
1138 | 0 | dmprintf(ptpriv->memory, "\nCFF: corrupt dictionary operand\n"); |
1139 | 0 | break; |
1140 | 0 | } |
1141 | 3.53k | args[n].ival = (int)args[n].fval; |
1142 | 3.53k | n++; |
1143 | 3.53k | } |
1144 | 94.9k | else if (b0 == 28 || b0 == 29 || (b0 >= 32 && b0 <= 254)) { |
1145 | | /* If we run out of data reading an integer at the very end of the stream, don't throw an error |
1146 | | just return. |
1147 | | */ |
1148 | 94.9k | bool near_end = ((e - p) <= 4); |
1149 | 94.9k | p = pdfi_read_cff_integer(p, e, b0, &args[n].ival); |
1150 | 94.9k | if (!p) { |
1151 | 38 | if (!near_end) |
1152 | 0 | code = gs_note_error(gs_error_invalidfont); |
1153 | 38 | dmprintf(ptpriv->memory, "\nCFF: corrupt dictionary operand\n"); |
1154 | 38 | break; |
1155 | 38 | } |
1156 | 94.8k | args[n].fval = (float)args[n].ival; |
1157 | 94.8k | n++; |
1158 | 94.8k | } |
1159 | 0 | else { |
1160 | 0 | dmprintf1(ptpriv->memory, "CFF: corrupt dictionary operand (b0 = %d)", b0); |
1161 | 0 | } |
1162 | 98.4k | } |
1163 | 145k | if (n >= PDFI_CFF_STACK_SIZE) { |
1164 | 3 | code = gs_error_invalidfont; |
1165 | 3 | break; |
1166 | 3 | } |
1167 | 145k | } |
1168 | | |
1169 | | /* recurse for the private dictionary */ |
1170 | 7.07k | if (do_priv && code >= 0) { |
1171 | 3.28k | byte *dend = font->cffdata + offsets->private_off + offsets->private_size; |
1172 | | |
1173 | 3.28k | if (dend > font->cffend) |
1174 | 316 | dend = font->cffend; |
1175 | | |
1176 | 3.28k | if (p == NULL) |
1177 | 0 | code = gs_error_invalidfont; |
1178 | 3.28k | else |
1179 | 3.28k | code = pdfi_read_cff_dict(font->cffdata + offsets->private_off, dend, ptpriv, offsets, false); |
1180 | | |
1181 | 3.28k | if (code < 0) |
1182 | 3.28k | dmprintf(ptpriv->memory, "CFF: cannot read private dictionary"); |
1183 | 3.28k | } |
1184 | | |
1185 | 7.07k | return code; |
1186 | 7.08k | } |
1187 | | |
1188 | | /* |
1189 | | * Get the number of items in an INDEX, and return |
1190 | | * a pointer to the end of the INDEX or NULL on |
1191 | | * failure. |
1192 | | */ |
1193 | | static byte * |
1194 | | pdfi_count_cff_index(byte *p, byte *e, int *countp) |
1195 | 13.2k | { |
1196 | 13.2k | int count, offsize, last; |
1197 | | |
1198 | 13.2k | if (p + 3 > e) { |
1199 | 113 | gs_throw(-1, "not enough data for index header"); |
1200 | 113 | return 0; |
1201 | 113 | } |
1202 | | |
1203 | 13.1k | count = u16(p); |
1204 | 13.1k | p += 2; |
1205 | 13.1k | *countp = count; |
1206 | | |
1207 | 13.1k | if (count == 0) |
1208 | 3.07k | return p; |
1209 | | |
1210 | 10.1k | offsize = *p++; |
1211 | | |
1212 | 10.1k | if (offsize < 1 || offsize > 4) { |
1213 | 97 | gs_throw(-1, "corrupt index header"); |
1214 | 97 | return 0; |
1215 | 97 | } |
1216 | | |
1217 | 10.0k | if (p + count * offsize > e) { |
1218 | 35 | gs_throw(-1, "not enough data for index offset table"); |
1219 | 35 | return 0; |
1220 | 35 | } |
1221 | | |
1222 | 9.97k | p += count * offsize; |
1223 | 9.97k | last = uofs(p, offsize); |
1224 | 9.97k | p += offsize; |
1225 | 9.97k | p--; /* stupid offsets */ |
1226 | | |
1227 | 9.97k | if (last < 0) { |
1228 | 4 | gs_throw(-1, "corrupt index"); |
1229 | 4 | return 0; |
1230 | 4 | } |
1231 | | |
1232 | 9.97k | if (p + last > e) { |
1233 | 245 | gs_throw(-1, "not enough data for index data"); |
1234 | 245 | return 0; |
1235 | 245 | } |
1236 | | |
1237 | 9.72k | p += last; |
1238 | | |
1239 | 9.72k | return p; |
1240 | 9.97k | } |
1241 | | |
1242 | | /* |
1243 | | * Locate and store pointers to the data of an |
1244 | | * item in the index that starts at 'p'. |
1245 | | * Return pointer to the end of the index, |
1246 | | * or NULL on failure. |
1247 | | */ |
1248 | | static byte * |
1249 | | pdfi_find_cff_index(byte *p, byte *e, int idx, byte ** pp, byte ** ep) |
1250 | 443k | { |
1251 | 443k | int count, offsize, sofs, eofs, last; |
1252 | | |
1253 | 443k | if (p == NULL) |
1254 | 1 | return 0; |
1255 | | |
1256 | 443k | if (p + 3 > e) { |
1257 | 11 | gs_throw(-1, "not enough data for index header"); |
1258 | 11 | return 0; |
1259 | 11 | } |
1260 | | |
1261 | 443k | count = u16(p); |
1262 | 443k | p += 2; |
1263 | 443k | if (count == 0) |
1264 | 105 | return 0; |
1265 | | |
1266 | 443k | offsize = *p++; |
1267 | | |
1268 | 443k | if (offsize < 1 || offsize > 4) { |
1269 | 13 | gs_throw(-1, "corrupt index header"); |
1270 | 13 | return 0; |
1271 | 13 | } |
1272 | | |
1273 | 443k | if (p + count * offsize > e) { |
1274 | 9 | gs_throw(-1, "not enough data for index offset table"); |
1275 | 9 | return 0; |
1276 | 9 | } |
1277 | | |
1278 | 443k | if (idx < 0 || idx >= count) { |
1279 | 75 | gs_throw(-1, "tried to access non-existing index item"); |
1280 | 75 | return 0; |
1281 | 75 | } |
1282 | | |
1283 | 443k | sofs = uofs(p + idx * offsize, offsize); |
1284 | 443k | eofs = uofs(p + (idx + 1) * offsize, offsize); |
1285 | 443k | last = uofs(p + count * offsize, offsize); |
1286 | | |
1287 | 443k | p += count * offsize; |
1288 | 443k | p += offsize; |
1289 | 443k | p--; /* stupid offsets */ |
1290 | | |
1291 | 443k | if (p + last > e) { |
1292 | 40 | gs_throw(-1, "not enough data for index data"); |
1293 | 40 | return 0; |
1294 | 40 | } |
1295 | | |
1296 | 443k | if (sofs < 0 || eofs < 0 || sofs > eofs || eofs > last) { |
1297 | 3.70k | gs_throw(-1, "corrupt index offset table"); |
1298 | 3.70k | return 0; |
1299 | 3.70k | } |
1300 | | |
1301 | 439k | *pp = p + sofs; |
1302 | 439k | *ep = p + eofs; |
1303 | | |
1304 | 439k | return p + last; |
1305 | 443k | } |
1306 | | |
1307 | | static int |
1308 | | pdfi_make_name_from_sid(pdf_context *ctx, pdf_obj ** nm, pdfi_cff_font_priv *font, cff_font_offsets *offsets, unsigned int sid) |
1309 | 132k | { |
1310 | 132k | gs_string str; |
1311 | 132k | byte *p; |
1312 | | |
1313 | 132k | if (sid < gs_c_known_encoding_lengths[10]) { |
1314 | 85.0k | gs_glyph gl = gs_c_known_encode(sid, 10); |
1315 | | |
1316 | 85.0k | (void)gs_c_glyph_name(gl, (gs_const_string *) &str); |
1317 | 85.0k | } |
1318 | 47.5k | else { |
1319 | 47.5k | byte *strp, *stre; |
1320 | | |
1321 | 47.5k | p = pdfi_find_cff_index(font->cffdata + offsets->strings_off, font->cffend, sid - gs_c_known_encoding_lengths[10], &strp, &stre); |
1322 | 47.5k | if (p == NULL) |
1323 | 104 | return_error(gs_error_rangecheck); |
1324 | 47.4k | str.data = strp; |
1325 | 47.4k | str.size = stre - strp; |
1326 | 47.4k | } |
1327 | 132k | return pdfi_name_alloc(ctx, str.data, str.size, nm); |
1328 | 132k | } |
1329 | | |
1330 | | static int |
1331 | | pdfi_make_string_from_sid(pdf_context *ctx, pdf_obj ** s0, pdfi_cff_font_priv *font, cff_font_offsets *offsets, unsigned int sid) |
1332 | 1.46k | { |
1333 | 1.46k | byte *p; |
1334 | 1.46k | int code; |
1335 | 1.46k | gs_string str; |
1336 | 1.46k | pdf_string *s = NULL; |
1337 | | |
1338 | 1.46k | if (sid < gs_c_known_encoding_lengths[10]) { |
1339 | 31 | gs_glyph gl = gs_c_known_encode(sid, 10); |
1340 | | |
1341 | 31 | (void)gs_c_glyph_name(gl, (gs_const_string *) &str); |
1342 | 31 | } |
1343 | 1.43k | else { |
1344 | 1.43k | byte *strp, *stre; |
1345 | | |
1346 | 1.43k | p = pdfi_find_cff_index(font->cffdata + offsets->strings_off, font->cffend, |
1347 | 1.43k | sid - gs_c_known_encoding_lengths[10], &strp, &stre); |
1348 | 1.43k | if (p == NULL) |
1349 | 1 | return_error(gs_error_rangecheck); |
1350 | 1.43k | str.data = strp; |
1351 | 1.43k | str.size = stre - strp; |
1352 | 1.43k | } |
1353 | 1.46k | code = pdfi_object_alloc(ctx, PDF_STRING, str.size, (pdf_obj **) &s); |
1354 | 1.46k | if (code < 0) |
1355 | 0 | return code; |
1356 | 1.46k | pdfi_countup(s); |
1357 | 1.46k | memcpy(s->data, str.data, str.size); |
1358 | 1.46k | s->length = str.size; |
1359 | | |
1360 | 1.46k | *s0 = (pdf_obj *) s; |
1361 | 1.46k | return 0; |
1362 | 1.46k | } |
1363 | | |
1364 | | static int |
1365 | | pdfi_cff_build_encoding(pdf_context *ctx, pdfi_gs_cff_font_priv *ptpriv, cff_font_offsets *offsets, |
1366 | | int (*charset_proc)(const byte *p, const byte *pe, unsigned int i)) |
1367 | 2.36k | { |
1368 | 2.36k | pdfi_cff_font_priv *font = &ptpriv->pdfcffpriv; |
1369 | 2.36k | int code = 0; |
1370 | 2.36k | byte *s, *e, *lp; |
1371 | 2.36k | pdf_string *pstr; |
1372 | 2.36k | unsigned int i, gid, enc_format = 0; |
1373 | 2.36k | int sid; |
1374 | 2.36k | pdf_name *ndname = NULL; |
1375 | 2.36k | unsigned char gid2char[256]; |
1376 | 2.36k | unsigned supp_enc_offset = 0; |
1377 | | |
1378 | 2.36k | if (offsets->encoding_off <= 1) { |
1379 | | /* Either standard or expert encoding */ |
1380 | 1.07k | pdf_name *enm = NULL; |
1381 | 1.07k | const char *const stdenc = "StandardEncoding"; |
1382 | 1.07k | const char *const expenc = "MacExpertEncoding"; |
1383 | 1.07k | char const *enctouse; |
1384 | | |
1385 | 1.07k | if (offsets->encoding_off < 1) { |
1386 | 1.06k | enctouse = stdenc; |
1387 | 1.06k | } |
1388 | 10 | else { |
1389 | 10 | enctouse = expenc; |
1390 | 10 | } |
1391 | 1.07k | code = pdfi_name_alloc(ctx, (byte *) enctouse, strlen(enctouse), (pdf_obj **) &enm); |
1392 | 1.07k | if (code >= 0) { |
1393 | 1.07k | pdfi_countup(enm); |
1394 | 1.07k | code = pdfi_create_Encoding(ctx, (pdf_obj *) enm, NULL, (pdf_obj **) &font->Encoding); |
1395 | 1.07k | pdfi_countdown(enm); |
1396 | 1.07k | } |
1397 | 1.07k | } |
1398 | 1.29k | else { |
1399 | 1.29k | if (font->cffdata + offsets->encoding_off > font->cffend) { |
1400 | 3 | code = gs_note_error(gs_error_invalidfont); |
1401 | 3 | } |
1402 | 1.28k | else { |
1403 | 1.28k | code = pdfi_object_alloc(ctx, PDF_ARRAY, 256, (pdf_obj **) &font->Encoding); |
1404 | 1.28k | if (code < 0) |
1405 | 0 | return code; |
1406 | | |
1407 | 1.28k | code = pdfi_name_alloc(ctx, (byte *) ".notdef", 7, (pdf_obj **) &ndname); |
1408 | 1.28k | if (code < 0) |
1409 | 0 | return code; |
1410 | | |
1411 | | |
1412 | 1.28k | pdfi_countup(font->Encoding); |
1413 | 1.28k | pdfi_countup(ndname); |
1414 | 1.28k | code = 0; |
1415 | | /* Prepopulate with notdefs */ |
1416 | 331k | for (i = 0; i < 256 && code >= 0; i++) { |
1417 | 329k | code = pdfi_array_put(ctx, font->Encoding, (uint64_t) i, (pdf_obj *) ndname); |
1418 | 329k | } |
1419 | | |
1420 | 1.28k | if (code >= 0) { |
1421 | 1.28k | byte *p = font->cffdata + offsets->encoding_off; |
1422 | | |
1423 | 1.28k | enc_format = p[0]; |
1424 | | |
1425 | 1.28k | lp = pdfi_find_cff_index(font->charstrings, font->cffend, 0, &s, &e); |
1426 | 1.28k | if (lp == NULL) { |
1427 | 8 | code = gs_note_error(gs_error_rangecheck); |
1428 | 8 | goto done; |
1429 | 8 | } |
1430 | 1.28k | code = pdfi_object_alloc(ctx, PDF_STRING, e - s, (pdf_obj **) &pstr); |
1431 | 1.28k | if (code < 0) |
1432 | 0 | goto done; |
1433 | 1.28k | memcpy(pstr->data, s, e - s); |
1434 | 1.28k | pdfi_countup(pstr); |
1435 | 1.28k | code = |
1436 | 1.28k | pdfi_dict_put_obj(ctx, font->CharStrings, (pdf_obj *) ndname, (pdf_obj *) pstr, true); |
1437 | 1.28k | pdfi_countdown(pstr); |
1438 | 1.28k | if (code < 0) { |
1439 | 0 | goto done; |
1440 | 0 | } |
1441 | 1.28k | pdfi_countdown(ndname); |
1442 | 1.28k | ndname = NULL; /* just to avoid bad things! */ |
1443 | | |
1444 | 1.28k | if ((enc_format &0x7f) == 0) { |
1445 | 809 | unsigned int n_codes = p[1]; |
1446 | | |
1447 | 809 | if (p + 2 + n_codes > font->cffend) { |
1448 | 0 | return_error(gs_error_invalidfont); |
1449 | 0 | } |
1450 | 809 | gid2char[0] = 0; |
1451 | 11.4k | for (i = 0; i < n_codes; i++) { |
1452 | 10.6k | gid2char[i + 1] = p[2 + i]; |
1453 | 10.6k | } |
1454 | 809 | memset(gid2char + n_codes + 1, 0, sizeof(gid2char) - n_codes - 1); |
1455 | 809 | supp_enc_offset = 2 + n_codes; |
1456 | 809 | } |
1457 | 472 | else if ((enc_format &0x7f) == 1) { |
1458 | 468 | unsigned int n_ranges = p[1]; |
1459 | 468 | unsigned int first, left, j, k = 1; |
1460 | | |
1461 | 468 | if (p + 2 + 2 * n_ranges > font->cffend) { |
1462 | 0 | return_error(gs_error_invalidfont); |
1463 | 0 | } |
1464 | 468 | gid2char[0] = 0; |
1465 | 3.76k | for (i = 0; i < n_ranges; i++) { |
1466 | 3.30k | first = p[2 + 2 * i]; |
1467 | 3.30k | left = p[3 + 2 * i]; |
1468 | 27.7k | for (j = 0; j <= left && k < 256; j++) |
1469 | 24.4k | gid2char[k++] = first + j; |
1470 | 3.30k | } |
1471 | 468 | memset(gid2char + k, 0, sizeof(gid2char) - k); |
1472 | 468 | supp_enc_offset = 2 * n_ranges + 2; |
1473 | 468 | } |
1474 | 4 | else { |
1475 | 4 | return_error(gs_error_rangecheck); |
1476 | 4 | } |
1477 | 1.28k | } |
1478 | 1.28k | } |
1479 | 1.29k | } |
1480 | 2.35k | if (code >= 0) { |
1481 | 2.34k | pdf_obj *gname; |
1482 | | |
1483 | 2.34k | code = 0; |
1484 | | |
1485 | 2.34k | lp = pdfi_find_cff_index(font->charstrings, font->cffend, 0, &s, &e); |
1486 | 2.34k | if (lp == NULL) { |
1487 | 1 | code = gs_note_error(gs_error_rangecheck); |
1488 | 1 | goto done; |
1489 | 1 | } |
1490 | 2.34k | code = pdfi_object_alloc(ctx, PDF_STRING, e - s, (pdf_obj **) &pstr); |
1491 | 2.34k | if (code < 0) |
1492 | 0 | goto done; |
1493 | 2.34k | memcpy(pstr->data, s, e - s); |
1494 | 2.34k | pdfi_countup(pstr); |
1495 | 2.34k | if (ptpriv->forcecid) { |
1496 | 112 | char buf[40]; |
1497 | 112 | int len = gs_snprintf(buf, sizeof(buf), "%d", 0); |
1498 | | |
1499 | 112 | code = pdfi_name_alloc(ctx, (byte *) buf, len, &gname); |
1500 | 112 | if (code < 0) { |
1501 | 0 | pdfi_countdown(pstr); |
1502 | 0 | return code; |
1503 | 0 | } |
1504 | 112 | pdfi_countup(gname); |
1505 | 112 | } |
1506 | 2.23k | else { |
1507 | 2.23k | code = pdfi_name_alloc(ctx, (byte *) ".notdef", 7, &gname); |
1508 | 2.23k | if (code < 0) { |
1509 | 0 | pdfi_countdown(pstr); |
1510 | 0 | goto done; |
1511 | 0 | } |
1512 | 2.23k | pdfi_countup(gname); |
1513 | 2.23k | } |
1514 | 2.34k | code = pdfi_dict_put_obj(ctx, font->CharStrings, gname, (pdf_obj *) pstr, true); |
1515 | 2.34k | pdfi_countdown(pstr); |
1516 | 2.34k | pdfi_countdown(gname); |
1517 | 2.34k | if (code < 0) |
1518 | 0 | goto done; |
1519 | | |
1520 | 165k | for (gid = 1; gid < font->ncharstrings && code >= 0; gid++) { |
1521 | | |
1522 | 163k | lp = pdfi_find_cff_index(font->charstrings, font->cffend, gid, &s, &e); |
1523 | 163k | if (lp == NULL) { |
1524 | 20 | code = gs_note_error(gs_error_rangecheck); |
1525 | 20 | continue; |
1526 | 20 | } |
1527 | 163k | code = pdfi_object_alloc(ctx, PDF_STRING, e - s, (pdf_obj **) &pstr); |
1528 | 163k | if (code < 0) |
1529 | 0 | return code; |
1530 | 163k | memcpy(pstr->data, s, e - s); |
1531 | 163k | pdfi_countup(pstr); |
1532 | | |
1533 | 163k | if (ptpriv->forcecid) { |
1534 | 30.6k | char buf[40]; |
1535 | 30.6k | int len = gs_snprintf(buf, sizeof(buf), "%d", gid); |
1536 | | |
1537 | 30.6k | code = pdfi_name_alloc(ctx, (byte *) buf, len, &gname); |
1538 | 30.6k | if (code < 0) { |
1539 | 0 | pdfi_countdown(pstr); |
1540 | 0 | return code; |
1541 | 0 | } |
1542 | 30.6k | } |
1543 | 132k | else { |
1544 | 132k | sid = (*charset_proc) (font->cffdata + offsets->charset_off + 1, font->cffend, gid - 1); |
1545 | 132k | if (sid < 0) { |
1546 | 0 | pdfi_countdown(pstr); |
1547 | 0 | return sid; |
1548 | 0 | } |
1549 | 132k | if ((code = pdfi_make_name_from_sid(ctx, &gname, font, offsets, sid)) < 0) { |
1550 | 104 | char buf[40]; |
1551 | 104 | int len = gs_snprintf(buf, sizeof(buf), "sid-%d", sid); |
1552 | | |
1553 | 104 | code = pdfi_name_alloc(ctx, (byte *) buf, len, &gname); |
1554 | 104 | if (code < 0) { |
1555 | 0 | pdfi_countdown(pstr); |
1556 | 0 | return code; |
1557 | 0 | } |
1558 | 104 | } |
1559 | 132k | } |
1560 | 163k | pdfi_countup(gname); |
1561 | 163k | code = pdfi_dict_put_obj(ctx, font->CharStrings, gname, (pdf_obj *) pstr, true); |
1562 | 163k | pdfi_countdown(pstr); |
1563 | 163k | if (code < 0) { |
1564 | 0 | pdfi_countdown(gname); |
1565 | 0 | return code; |
1566 | 0 | } |
1567 | 163k | if (offsets->encoding_off > 1 && gid < 256) { |
1568 | 56.9k | code = pdfi_array_put(ctx, font->Encoding, (int64_t) gid2char[gid], gname); |
1569 | 56.9k | } |
1570 | 163k | pdfi_countdown(gname); |
1571 | 163k | } |
1572 | | |
1573 | 2.34k | if (offsets->encoding_off > 1 && (enc_format & 0x80)) { |
1574 | 5 | unsigned int n_supp, charcode, sid; |
1575 | 5 | byte *p = font->cffdata + offsets->encoding_off + supp_enc_offset; |
1576 | 5 | pdf_obj *gname; |
1577 | | |
1578 | 5 | n_supp = p[0]; |
1579 | | |
1580 | 30 | for (i = 0; i < n_supp && code >= 0; i++) { |
1581 | 25 | charcode = p[1 + 3 * i]; |
1582 | 25 | sid = u16(p + 2 + 3 * i); |
1583 | | |
1584 | 25 | if ((code = pdfi_make_name_from_sid(ctx, &gname, font, offsets, sid)) < 0) { |
1585 | 0 | char buf[40]; |
1586 | 0 | int len = gs_snprintf(buf, sizeof(buf), "sid-%d", sid); |
1587 | |
|
1588 | 0 | if (len > 0) |
1589 | 0 | code = pdfi_name_alloc(ctx, (byte *) buf, len, &gname); |
1590 | 0 | else |
1591 | 0 | code = 0; |
1592 | |
|
1593 | 0 | if (code < 0) |
1594 | 0 | continue; |
1595 | 0 | } |
1596 | 25 | pdfi_countup(gname); |
1597 | 25 | code = pdfi_array_put(ctx, font->Encoding, (int64_t) charcode, gname); |
1598 | 25 | pdfi_countdown(gname); |
1599 | 25 | } |
1600 | 5 | } |
1601 | 2.34k | } |
1602 | 2.35k | done: |
1603 | 2.35k | if (code < 0) { |
1604 | 32 | pdfi_countdown(ndname); |
1605 | 32 | } |
1606 | 2.35k | return code; |
1607 | 2.35k | } |
1608 | | |
1609 | | |
1610 | | /* |
1611 | | * Scan the CFF file structure and extract important data. |
1612 | | */ |
1613 | | |
1614 | | static int |
1615 | | pdfi_read_cff(pdf_context *ctx, pdfi_gs_cff_font_priv *ptpriv) |
1616 | 3.23k | { |
1617 | 3.23k | pdfi_cff_font_priv *font = &ptpriv->pdfcffpriv; |
1618 | 3.23k | byte *pstore, *p = font->cffdata; |
1619 | 3.23k | byte *e = font->cffend; |
1620 | 3.23k | byte *dictp, *dicte; |
1621 | 3.23k | byte *strp, *stre; |
1622 | 3.23k | byte *nms, *nmp, *nme; |
1623 | 3.23k | int count; |
1624 | 3.23k | int i, code = 0; |
1625 | 3.23k | cff_font_offsets offsets = { 0 }; |
1626 | 3.23k | int (*charset_proc)(const byte *p, const byte *pe, unsigned int i); |
1627 | 3.23k | int major, minor, hdrsize; |
1628 | | |
1629 | | /* CFF header */ |
1630 | 3.23k | if (p + 4 > e) |
1631 | 0 | return gs_throw(gs_error_invalidfont, "not enough data for header"); |
1632 | | |
1633 | 3.23k | major = *p; |
1634 | 3.23k | minor = *(p + 1); |
1635 | 3.23k | hdrsize = *(p + 2); |
1636 | | |
1637 | 3.23k | if (major != 1 || minor != 0) |
1638 | 0 | return gs_throw(gs_error_invalidfont, "not a CFF 1.0 file"); |
1639 | | |
1640 | 3.23k | if (p + hdrsize > e) |
1641 | 1 | return gs_throw(gs_error_invalidfont, "not enough data for extended header"); |
1642 | 3.23k | p += hdrsize; |
1643 | | |
1644 | | /* Name INDEX */ |
1645 | 3.23k | nms = p; |
1646 | 3.23k | p = pdfi_count_cff_index(p, e, &count); |
1647 | 3.23k | if (p == NULL) |
1648 | 17 | return gs_throw(gs_error_invalidfont, "cannot read name index"); |
1649 | 3.21k | if (count != 1) |
1650 | 0 | return gs_throw(gs_error_invalidfont, "file did not contain exactly one font"); |
1651 | | |
1652 | 3.21k | nms = pdfi_find_cff_index(nms, e, 0, &nmp, &nme); |
1653 | 3.21k | if (!nms) |
1654 | 1 | return gs_throw(gs_error_invalidfont, "cannot read names index"); |
1655 | 3.21k | else { |
1656 | 3.21k | int len = nme - nmp < sizeof(ptpriv->key_name.chars) ? nme - nmp : sizeof(ptpriv->key_name.chars); |
1657 | 3.21k | memcpy(ptpriv->key_name.chars, nmp, len); |
1658 | 3.21k | memcpy(ptpriv->font_name.chars, nmp, len); |
1659 | 3.21k | ptpriv->key_name.size = ptpriv->font_name.size = len; |
1660 | 3.21k | } |
1661 | | |
1662 | | /* Top Dict INDEX */ |
1663 | 3.21k | p = pdfi_find_cff_index(p, e, 0, &dictp, &dicte); |
1664 | 3.21k | if (p == NULL) |
1665 | 32 | return gs_throw(gs_error_invalidfont, "cannot read top dict index"); |
1666 | | |
1667 | | /* String index */ |
1668 | 3.18k | pstore = p; |
1669 | 3.18k | p = pdfi_find_cff_index(p, e, 0, &strp, &stre); |
1670 | | |
1671 | 3.18k | offsets.strings_off = pstore - font->cffdata; |
1672 | | |
1673 | 3.18k | p = pdfi_count_cff_index(pstore, e, &count); |
1674 | 3.18k | if (p == NULL) |
1675 | 41 | return_error(gs_error_invalidfont); |
1676 | | |
1677 | 3.14k | offsets.strings_size = (unsigned int)count; |
1678 | | |
1679 | | /* Global Subr INDEX */ |
1680 | 3.14k | font->gsubrs = p; |
1681 | 3.14k | p = pdfi_count_cff_index(p, e, &font->NumGlobalSubrs); |
1682 | 3.14k | if (p == NULL) { |
1683 | 26 | font->GlobalSubrs = NULL; |
1684 | 26 | font->NumGlobalSubrs = 0; |
1685 | 26 | } |
1686 | | /* Read the top and private dictionaries */ |
1687 | 3.14k | code = pdfi_read_cff_dict(dictp, dicte, ptpriv, &offsets, true); |
1688 | 3.14k | if (code < 0) |
1689 | 41 | return gs_rethrow(code, "cannot read top dictionary"); |
1690 | | |
1691 | | /* Check the subrs index */ |
1692 | 3.10k | font->NumSubrs = 0; |
1693 | 3.10k | if (font->subrs) { |
1694 | 217 | p = pdfi_count_cff_index(font->subrs, e, &font->NumSubrs); |
1695 | 217 | if (p == NULL || font->NumSubrs > 65536) { |
1696 | 91 | font->Subrs = NULL; |
1697 | 91 | font->NumSubrs = 0; |
1698 | 91 | } |
1699 | 126 | else { |
1700 | 126 | ptpriv->type1data.subroutineNumberBias = subrbias(font->NumSubrs); |
1701 | 126 | } |
1702 | 217 | } |
1703 | | |
1704 | | |
1705 | 3.10k | font->GlobalSubrs = NULL; |
1706 | 3.10k | if (font->NumGlobalSubrs > 0 && font->NumGlobalSubrs <= 65536) { |
1707 | 138 | ptpriv->type1data.gsubrNumberBias = subrbias(font->NumGlobalSubrs); |
1708 | 138 | code = pdfi_object_alloc(ctx, PDF_ARRAY, font->NumGlobalSubrs, (pdf_obj **) &font->GlobalSubrs); |
1709 | 138 | if (code >= 0) { |
1710 | 138 | font->GlobalSubrs->refcnt = 1; |
1711 | 57.1k | for (i = 0; i < font->NumGlobalSubrs; i++) { |
1712 | 56.9k | pdf_string *gsubrstr; |
1713 | | |
1714 | 56.9k | p = pdfi_find_cff_index(font->gsubrs, font->cffend, i, &strp, &stre); |
1715 | 56.9k | if (p) { |
1716 | 54.6k | code = pdfi_object_alloc(ctx, PDF_STRING, stre - strp, (pdf_obj **) &gsubrstr); |
1717 | 54.6k | if (code >= 0) { |
1718 | 54.6k | memcpy(gsubrstr->data, strp, gsubrstr->length); |
1719 | 54.6k | code = |
1720 | 54.6k | pdfi_array_put(ctx, font->GlobalSubrs, (uint64_t) i, |
1721 | 54.6k | (pdf_obj *) gsubrstr); |
1722 | 54.6k | if (code < 0) { |
1723 | 0 | gsubrstr->refcnt = 1; |
1724 | 0 | pdfi_countdown(gsubrstr); |
1725 | 0 | } |
1726 | 54.6k | } |
1727 | 54.6k | } |
1728 | 2.29k | else { |
1729 | 2.29k | code = pdfi_array_put(ctx, font->GlobalSubrs, (uint64_t) i, PDF_NULL_OBJ); |
1730 | 2.29k | if (code < 0) { |
1731 | 0 | pdfi_countdown(font->GlobalSubrs); |
1732 | 0 | font->GlobalSubrs = NULL; |
1733 | 0 | } |
1734 | 2.29k | } |
1735 | 56.9k | } |
1736 | 138 | } |
1737 | 138 | } |
1738 | | |
1739 | 3.10k | font->Subrs = NULL; |
1740 | 3.10k | if (font->NumSubrs > 0) { |
1741 | 126 | code = pdfi_object_alloc(ctx, PDF_ARRAY, font->NumSubrs, (pdf_obj **) &font->Subrs); |
1742 | 126 | if (code >= 0 && font->Subrs != NULL) { |
1743 | 126 | font->Subrs->refcnt = 1; |
1744 | 20.8k | for (i = 0; i < font->NumSubrs; i++) { |
1745 | 20.7k | pdf_string *subrstr; |
1746 | | |
1747 | 20.7k | p = pdfi_find_cff_index(font->subrs, font->cffend, i, &strp, &stre); |
1748 | 20.7k | if (p) { |
1749 | 19.4k | code = pdfi_object_alloc(ctx, PDF_STRING, stre - strp, (pdf_obj **) &subrstr); |
1750 | 19.4k | if (code >= 0) { |
1751 | 19.4k | memcpy(subrstr->data, strp, subrstr->length); |
1752 | 19.4k | code = pdfi_array_put(ctx, font->Subrs, (uint64_t) i, (pdf_obj *) subrstr); |
1753 | 19.4k | if (code < 0) { |
1754 | 0 | subrstr->refcnt = 1; |
1755 | 0 | pdfi_countdown(subrstr); |
1756 | 0 | } |
1757 | 19.4k | } |
1758 | 19.4k | } |
1759 | 1.30k | else { |
1760 | 1.30k | code = pdfi_array_put(ctx, font->Subrs, (uint64_t) i, PDF_NULL_OBJ); |
1761 | 1.30k | if (code < 0) { |
1762 | 0 | pdfi_countdown(font->Subrs); |
1763 | 0 | font->Subrs = NULL; |
1764 | 0 | font->NumSubrs = 0; |
1765 | 0 | break; |
1766 | 0 | } |
1767 | 1.30k | } |
1768 | 20.7k | } |
1769 | 126 | } |
1770 | 126 | } |
1771 | | |
1772 | | /* Check the charstrings index */ |
1773 | 3.10k | if (font->charstrings) { |
1774 | 3.09k | p = pdfi_count_cff_index(font->charstrings, e, &font->ncharstrings); |
1775 | 3.09k | if (!p || font->ncharstrings > 65535) |
1776 | 306 | return gs_rethrow(-1, "cannot read charstrings index"); |
1777 | 3.09k | } |
1778 | 2.79k | code = pdfi_object_alloc(ctx, PDF_DICT, font->ncharstrings, (pdf_obj **) &font->CharStrings); |
1779 | 2.79k | if (code < 0) |
1780 | 0 | return code; |
1781 | 2.79k | pdfi_countup(font->CharStrings); |
1782 | | |
1783 | 2.79k | switch (offsets.charset_off) { |
1784 | 56 | case 0: |
1785 | 56 | charset_proc = iso_adobe_charset_proc; |
1786 | 56 | break; |
1787 | 0 | case 1: |
1788 | 0 | charset_proc = expert_charset_proc; |
1789 | 0 | break; |
1790 | 0 | case 2: |
1791 | 0 | charset_proc = expert_subset_charset_proc; |
1792 | 0 | break; |
1793 | 2.74k | default:{ |
1794 | 2.74k | if (font->cffdata + offsets.charset_off >= font->cffend) |
1795 | 0 | return_error(gs_error_rangecheck); |
1796 | | |
1797 | 2.74k | switch ((int)font->cffdata[offsets.charset_off]) { |
1798 | 1.21k | case 0: |
1799 | 1.21k | charset_proc = format0_charset_proc; |
1800 | 1.21k | break; |
1801 | 1.49k | case 1: |
1802 | 1.49k | charset_proc = format1_charset_proc; |
1803 | 1.49k | break; |
1804 | 14 | case 2: |
1805 | 14 | charset_proc = format2_charset_proc; |
1806 | 14 | break; |
1807 | 17 | default: |
1808 | 17 | return_error(gs_error_rangecheck); |
1809 | 2.74k | } |
1810 | 2.74k | } |
1811 | 2.79k | } |
1812 | | |
1813 | 2.77k | if (offsets.have_ros) { /* CIDFont */ |
1814 | 416 | int fdarray_size; |
1815 | 416 | bool topdict_matrix = offsets.have_matrix; |
1816 | 416 | int (*fdselect_proc)(const byte *p, const byte *pe, unsigned int i); |
1817 | | |
1818 | 416 | p = pdfi_count_cff_index(font->cffdata + offsets.fdarray_off, e, &fdarray_size); |
1819 | 416 | if (!p || fdarray_size < 1 || fdarray_size > 64) /* 64 is arbitrary, but seems a reasonable upper limit */ |
1820 | 16 | return gs_rethrow(-1, "cannot read charstrings index"); |
1821 | | |
1822 | 400 | ptpriv->cidata.FDBytes = 1; /* Basically, always 1 just now */ |
1823 | | |
1824 | 400 | ptpriv->cidata.FDArray = (gs_font_type1 **) gs_alloc_bytes(ctx->memory, fdarray_size * sizeof(gs_font_type1 *), "pdfi_read_cff(fdarray)"); |
1825 | 400 | if (!ptpriv->cidata.FDArray) |
1826 | 0 | return_error(gs_error_VMerror); |
1827 | 400 | ptpriv->cidata.FDArray_size = fdarray_size; |
1828 | | |
1829 | 400 | code = pdfi_object_alloc(ctx, PDF_ARRAY, fdarray_size, (pdf_obj **) &font->FDArray); |
1830 | 400 | if (code < 0) { |
1831 | 0 | gs_free_object(ctx->memory, ptpriv->cidata.FDArray, "pdfi_read_cff(fdarray)"); |
1832 | 0 | ptpriv->cidata.FDArray = NULL; |
1833 | 0 | } |
1834 | 400 | else { |
1835 | 400 | pdfi_countup(font->FDArray); |
1836 | 400 | code = 0; |
1837 | 1.05k | for (i = 0; i < fdarray_size && code == 0; i++) { |
1838 | 659 | byte *fddictp, *fddicte; |
1839 | 659 | pdfi_gs_cff_font_priv fdptpriv = { 0 }; |
1840 | 659 | pdf_font_cff *pdffont = NULL; |
1841 | 659 | gs_font_type1 *pt1font; |
1842 | | |
1843 | 659 | pdfi_init_cff_font_priv(ctx, &fdptpriv, font->cffdata, (font->cffend - font->cffdata), true); |
1844 | | |
1845 | 659 | offsets.private_off = 0; |
1846 | | |
1847 | 659 | p = pdfi_find_cff_index(font->cffdata + offsets.fdarray_off, e, i, &fddictp, &fddicte); |
1848 | 659 | if (!p) { |
1849 | 0 | ptpriv->cidata.FDArray[i] = NULL; |
1850 | 0 | code = gs_note_error(gs_error_invalidfont); |
1851 | 0 | continue; |
1852 | 0 | } |
1853 | 659 | if (fddicte > font->cffend) |
1854 | 0 | fddicte = font->cffend; |
1855 | | |
1856 | 659 | code = pdfi_read_cff_dict(fddictp, fddicte, &fdptpriv, &offsets, true); |
1857 | 659 | if (code < 0) { |
1858 | 5 | ptpriv->cidata.FDArray[i] = NULL; |
1859 | 5 | code = gs_note_error(gs_error_invalidfont); |
1860 | 5 | continue; |
1861 | 5 | } |
1862 | 654 | code = pdfi_alloc_cff_font(ctx, &pdffont, 0, true); |
1863 | 654 | if (code < 0) { |
1864 | 0 | ptpriv->cidata.FDArray[i] = NULL; |
1865 | 0 | code = gs_note_error(gs_error_invalidfont); |
1866 | 0 | continue; |
1867 | 0 | } |
1868 | 654 | pt1font = (gs_font_type1 *) pdffont->pfont; |
1869 | 654 | memcpy(pt1font, &fdptpriv, sizeof(pdfi_gs_cff_font_common_priv)); |
1870 | 654 | memcpy(&pt1font->data, &fdptpriv.type1data, sizeof(fdptpriv.type1data)); |
1871 | 654 | pt1font->base = (gs_font *) pdffont->pfont; |
1872 | | |
1873 | 654 | if (!topdict_matrix && offsets.have_matrix) { |
1874 | 2 | gs_matrix newfmat, onekmat = { 1000, 0, 0, 1000, 0, 0 }; |
1875 | 2 | code = gs_matrix_multiply(&onekmat, &pt1font->FontMatrix, &newfmat); |
1876 | 2 | memcpy(&pt1font->FontMatrix, &newfmat, sizeof(newfmat)); |
1877 | 2 | } |
1878 | | |
1879 | 654 | pt1font->FAPI = NULL; |
1880 | 654 | pt1font->client_data = pdffont; |
1881 | | |
1882 | | /* Check the subrs index */ |
1883 | 654 | pdffont->Subrs = NULL; |
1884 | 654 | if (fdptpriv.pdfcffpriv.subrs) { |
1885 | 2 | p = pdfi_count_cff_index(fdptpriv.pdfcffpriv.subrs, e, &pdffont->NumSubrs); |
1886 | 2 | if (!p) { |
1887 | 0 | pdffont->Subrs = NULL; |
1888 | 0 | pdffont->NumSubrs = 0; |
1889 | 0 | } |
1890 | 2 | } |
1891 | | |
1892 | 654 | if (pdffont->NumSubrs > 0) { |
1893 | 2 | code = pdfi_object_alloc(ctx, PDF_ARRAY, pdffont->NumSubrs, (pdf_obj **) &pdffont->Subrs); |
1894 | 2 | if (code >= 0) { |
1895 | 2 | int j; |
1896 | | |
1897 | 2 | pdffont->Subrs->refcnt = 1; |
1898 | 880 | for (j = 0; j < pdffont->NumSubrs; j++) { |
1899 | 878 | pdf_string *subrstr; |
1900 | | |
1901 | 878 | p = pdfi_find_cff_index(fdptpriv.pdfcffpriv.subrs, e, j, &strp, &stre); |
1902 | 878 | if (p) { |
1903 | 878 | code = pdfi_object_alloc(ctx, PDF_STRING, stre - strp, (pdf_obj **) &subrstr); |
1904 | 878 | if (code >= 0) { |
1905 | 878 | memcpy(subrstr->data, strp, subrstr->length); |
1906 | 878 | code = pdfi_array_put(ctx, pdffont->Subrs, (uint64_t) j, (pdf_obj *) subrstr); |
1907 | 878 | if (code < 0) { |
1908 | 0 | subrstr->refcnt = 1; |
1909 | 0 | pdfi_countdown(subrstr); |
1910 | 0 | } |
1911 | 878 | } |
1912 | 878 | } |
1913 | 878 | } |
1914 | 2 | } |
1915 | 2 | } |
1916 | | |
1917 | 654 | pdffont->GlobalSubrs = font->GlobalSubrs; |
1918 | 654 | pdffont->NumGlobalSubrs = font->NumGlobalSubrs; |
1919 | 654 | pdfi_countup(pdffont->GlobalSubrs); |
1920 | 654 | pdffont->CharStrings = font->CharStrings; |
1921 | 654 | pdfi_countup(pdffont->CharStrings); |
1922 | 654 | pt1font->data.subroutineNumberBias = subrbias(pdffont->NumSubrs); |
1923 | 654 | pt1font->data.gsubrNumberBias = subrbias(pdffont->NumGlobalSubrs); |
1924 | | |
1925 | 654 | ptpriv->cidata.FDArray[i] = pt1font; |
1926 | 654 | (void)pdfi_array_put(ctx, font->FDArray, i, (pdf_obj *) pdffont); |
1927 | 654 | pdfi_countdown(pdffont); |
1928 | 654 | } |
1929 | 400 | if (code < 0) { |
1930 | 5 | pdfi_countdown(font->FDArray); |
1931 | 5 | font->FDArray = NULL; |
1932 | 51 | for (i = 0; i < ptpriv->cidata.FDArray_size; i++) { |
1933 | 46 | ptpriv->cidata.FDArray[i] = NULL; |
1934 | 46 | } |
1935 | 5 | } |
1936 | 395 | else { |
1937 | 395 | if (font->cffdata + offsets.fdselect_off > font->cffend) |
1938 | 2 | return_error(gs_error_rangecheck); |
1939 | | |
1940 | 393 | switch ((int)font->cffdata[offsets.fdselect_off]) { |
1941 | 240 | case 0: |
1942 | 240 | fdselect_proc = format0_fdselect_proc; |
1943 | 240 | break; |
1944 | 150 | case 3: |
1945 | 150 | fdselect_proc = format3_fdselect_proc; |
1946 | 150 | break; |
1947 | 3 | default: |
1948 | 3 | return_error(gs_error_rangecheck); |
1949 | 393 | } |
1950 | | |
1951 | 390 | if (font->ncharstrings > 0) { |
1952 | 390 | int maxcid = 0; |
1953 | 139k | for (i = 0; i < font->ncharstrings; i++) { |
1954 | 138k | int fd, g; |
1955 | 138k | char gkey[64]; |
1956 | 138k | pdf_string *charstr; |
1957 | | |
1958 | 138k | fd = fdarray_size <= 1 ? 0 : (*fdselect_proc) (font->cffdata + offsets.fdselect_off + 1, font->cffend, i); |
1959 | | |
1960 | 138k | p = pdfi_find_cff_index(font->charstrings, font->cffend, i, &strp, &stre); |
1961 | 138k | if (!p) |
1962 | 48 | continue; |
1963 | | |
1964 | 138k | code = pdfi_object_alloc(ctx, PDF_STRING, (stre - strp) + 1, (pdf_obj **) &charstr); |
1965 | 138k | if (code < 0) |
1966 | 0 | continue; |
1967 | 138k | charstr->data[0] = (byte) fd; |
1968 | 138k | memcpy(charstr->data + 1, strp, charstr->length - 1); |
1969 | | |
1970 | 138k | if (i == 0) { |
1971 | 390 | g = 0; |
1972 | 390 | } |
1973 | 138k | else { |
1974 | 138k | g = (*charset_proc) (font->cffdata + offsets.charset_off + 1, font->cffend, i - 1); |
1975 | 138k | } |
1976 | | |
1977 | 138k | if (g > maxcid) maxcid = g; |
1978 | 138k | gs_snprintf(gkey, sizeof(gkey), "%d", g); |
1979 | 138k | code = pdfi_dict_put_unchecked(ctx, font->CharStrings, gkey, (pdf_obj *) charstr); |
1980 | 138k | } |
1981 | 390 | if (maxcid > ptpriv->pdfcffpriv.cidcount - 1) |
1982 | 13 | ptpriv->pdfcffpriv.cidcount = maxcid + 1; |
1983 | 390 | } |
1984 | 390 | } |
1985 | 400 | } |
1986 | 400 | } |
1987 | 2.36k | else { |
1988 | 2.36k | code = pdfi_cff_build_encoding(ctx, ptpriv, &offsets, charset_proc); |
1989 | 2.36k | } |
1990 | 2.75k | return code; |
1991 | 2.77k | } |
1992 | | |
1993 | | static int |
1994 | | pdfi_alloc_cff_cidfont(pdf_context *ctx, pdf_cidfont_type0 ** font, uint32_t obj_num) |
1995 | 497 | { |
1996 | 497 | pdf_cidfont_type0 *cffcidfont = NULL; |
1997 | 497 | gs_font_cid0 *pfont = NULL; |
1998 | 497 | gs_matrix defmat = { 0.001f, 0.0f, 0.0f, 0.001f, 0.0f, 0.0f }; |
1999 | | |
2000 | 497 | cffcidfont = (pdf_cidfont_type0 *) gs_alloc_bytes(ctx->memory, sizeof(pdf_cidfont_type0), "pdfi (cff pdf_cidfont_type0)"); |
2001 | 497 | if (cffcidfont == NULL) |
2002 | 0 | return_error(gs_error_VMerror); |
2003 | | |
2004 | 497 | memset(cffcidfont, 0x00, sizeof(pdf_cidfont_type0)); |
2005 | 497 | cffcidfont->ctx = ctx; |
2006 | 497 | cffcidfont->type = PDF_FONT; |
2007 | 497 | cffcidfont->pdfi_font_type = e_pdf_cidfont_type0; |
2008 | | |
2009 | | #if REFCNT_DEBUG |
2010 | | cffcidfont->UID = ctx->UID++; |
2011 | | dmprintf2(ctx->memory, "Allocated object of type %c with UID %" PRIi64 "\n", cffcidfont->type, |
2012 | | cffcidfont->UID); |
2013 | | #endif |
2014 | | |
2015 | 497 | pdfi_countup(cffcidfont); |
2016 | | |
2017 | 497 | pfont = (gs_font_cid0 *) gs_alloc_struct(ctx->memory, gs_font_cid0, &st_gs_font_cid0, "pdfi (cff cid pfont)"); |
2018 | 497 | if (pfont == NULL) { |
2019 | 0 | pdfi_countdown(cffcidfont); |
2020 | 0 | return_error(gs_error_VMerror); |
2021 | 0 | } |
2022 | 497 | memset(pfont, 0x00, sizeof(gs_font_cid0)); |
2023 | | |
2024 | 497 | cffcidfont->pfont = (gs_font_base *) pfont; |
2025 | 497 | memcpy(&pfont->orig_FontMatrix, &defmat, sizeof(defmat)); |
2026 | 497 | memcpy(&pfont->FontMatrix, &defmat, sizeof(defmat)); |
2027 | 497 | pfont->next = pfont->prev = 0; |
2028 | 497 | pfont->memory = ctx->memory; |
2029 | 497 | pfont->dir = ctx->font_dir; |
2030 | 497 | pfont->is_resource = false; |
2031 | 497 | gs_notify_init(&pfont->notify_list, ctx->memory); |
2032 | 497 | pfont->base = (gs_font *) cffcidfont->pfont; |
2033 | 497 | pfont->client_data = cffcidfont; |
2034 | 497 | pfont->WMode = 0; |
2035 | 497 | pfont->PaintType = 0; |
2036 | 497 | pfont->StrokeWidth = 0; |
2037 | 497 | pfont->is_cached = 0; |
2038 | 497 | pfont->FAPI = NULL; |
2039 | 497 | pfont->FAPI_font_data = NULL; |
2040 | 497 | pfont->procs.init_fstack = gs_type0_init_fstack; |
2041 | 497 | pfont->procs.next_char_glyph = gs_default_next_char_glyph; |
2042 | 497 | pfont->FontType = ft_CID_encrypted; |
2043 | 497 | pfont->ExactSize = fbit_use_outlines; |
2044 | 497 | pfont->InBetweenSize = fbit_use_outlines; |
2045 | 497 | pfont->TransformedChar = fbit_use_outlines; |
2046 | | /* We may want to do something clever with an XUID here */ |
2047 | 497 | pfont->id = gs_next_ids(ctx->memory, 1); |
2048 | 497 | uid_set_invalid(&pfont->UID); |
2049 | | |
2050 | | /* The buildchar proc will be filled in by FAPI - |
2051 | | we won't worry about working without FAPI */ |
2052 | 497 | pfont->procs.encode_char = pdfi_encode_char; |
2053 | 497 | pfont->procs.glyph_name = ctx->get_glyph_name; |
2054 | 497 | pfont->procs.decode_glyph = pdfi_decode_glyph; |
2055 | 497 | pfont->procs.define_font = gs_no_define_font; |
2056 | 497 | pfont->procs.make_font = gs_no_make_font; |
2057 | 497 | pfont->procs.font_info = gs_default_font_info; |
2058 | 497 | pfont->procs.glyph_info = gs_default_glyph_info; |
2059 | 497 | pfont->procs.glyph_outline = pdfi_cff_glyph_outline; |
2060 | 497 | pfont->procs.build_char = NULL; |
2061 | 497 | pfont->procs.same_font = gs_default_same_font; |
2062 | 497 | pfont->procs.enumerate_glyph = pdfi_cff_enumerate_glyph; |
2063 | | |
2064 | 497 | pfont->cidata.glyph_data = pdfi_cff_cid_glyph_data; |
2065 | | |
2066 | 497 | pfont->encoding_index = 1; /****** WRONG ******/ |
2067 | 497 | pfont->nearest_encoding_index = 1; /****** WRONG ******/ |
2068 | | |
2069 | 497 | pfont->client_data = (void *)cffcidfont; |
2070 | | |
2071 | 497 | *font = cffcidfont; |
2072 | 497 | return 0; |
2073 | 497 | } |
2074 | | |
2075 | | static int |
2076 | | pdfi_alloc_cff_font(pdf_context *ctx, pdf_font_cff ** font, uint32_t obj_num, bool for_fdarray) |
2077 | 2.98k | { |
2078 | 2.98k | pdf_font_cff *cfffont = NULL; |
2079 | 2.98k | gs_font_type1 *pfont = NULL; |
2080 | 2.98k | gs_matrix defmat_font = { 0.001f, 0.0f, 0.0f, 0.001f, 0.0f, 0.0f }; |
2081 | 2.98k | gs_matrix defmat_fd = { 1.00f, 0.0f, 0.0f, 1.000f, 0.0f, 0.0f }; |
2082 | 2.98k | gs_matrix *defmat = (for_fdarray ? &defmat_fd : &defmat_font); |
2083 | | |
2084 | 2.98k | cfffont = (pdf_font_cff *) gs_alloc_bytes(ctx->memory, sizeof(pdf_font_cff), "pdfi (cff pdf_font)"); |
2085 | 2.98k | if (cfffont == NULL) |
2086 | 0 | return_error(gs_error_VMerror); |
2087 | | |
2088 | 2.98k | memset(cfffont, 0x00, sizeof(pdf_font_cff)); |
2089 | 2.98k | cfffont->ctx = ctx; |
2090 | 2.98k | cfffont->type = PDF_FONT; |
2091 | 2.98k | cfffont->pdfi_font_type = e_pdf_font_cff; |
2092 | | |
2093 | | #if REFCNT_DEBUG |
2094 | | cfffont->UID = ctx->UID++; |
2095 | | dmprintf2(ctx->memory, "Allocated object of type %c with UID %" PRIi64 "\n", cfffont->type, |
2096 | | cfffont->UID); |
2097 | | #endif |
2098 | | |
2099 | 2.98k | pdfi_countup(cfffont); |
2100 | | |
2101 | 2.98k | pfont = (gs_font_type1 *) gs_alloc_struct(ctx->memory, gs_font_type1, &st_gs_font_type1, "pdfi (truetype pfont)"); |
2102 | 2.98k | if (pfont == NULL) { |
2103 | 0 | pdfi_countdown(cfffont); |
2104 | 0 | return_error(gs_error_VMerror); |
2105 | 0 | } |
2106 | 2.98k | memset(pfont, 0x00, sizeof(gs_font_type1)); |
2107 | | |
2108 | 2.98k | cfffont->pfont = (gs_font_base *) pfont; |
2109 | 2.98k | memcpy(&pfont->orig_FontMatrix, defmat, sizeof(*defmat)); |
2110 | 2.98k | memcpy(&pfont->FontMatrix, defmat, sizeof(*defmat)); |
2111 | 2.98k | pfont->next = pfont->prev = 0; |
2112 | 2.98k | pfont->memory = ctx->memory; |
2113 | 2.98k | pfont->dir = ctx->font_dir; |
2114 | 2.98k | pfont->is_resource = false; |
2115 | 2.98k | gs_notify_init(&pfont->notify_list, ctx->memory); |
2116 | 2.98k | pfont->base = (gs_font *) cfffont->pfont; |
2117 | 2.98k | pfont->client_data = cfffont; |
2118 | 2.98k | pfont->WMode = 0; |
2119 | 2.98k | pfont->PaintType = 0; |
2120 | 2.98k | pfont->StrokeWidth = 0; |
2121 | 2.98k | pfont->is_cached = 0; |
2122 | 2.98k | pfont->FAPI = NULL; |
2123 | 2.98k | pfont->FAPI_font_data = NULL; |
2124 | 2.98k | pfont->procs.init_fstack = gs_default_init_fstack; |
2125 | 2.98k | pfont->procs.next_char_glyph = gs_default_next_char_glyph; |
2126 | 2.98k | pfont->FontType = ft_encrypted2; |
2127 | 2.98k | pfont->ExactSize = fbit_use_outlines; |
2128 | 2.98k | pfont->InBetweenSize = fbit_use_outlines; |
2129 | 2.98k | pfont->TransformedChar = fbit_use_outlines; |
2130 | | /* We may want to do something clever with an XUID here */ |
2131 | 2.98k | pfont->id = gs_next_ids(ctx->memory, 1); |
2132 | 2.98k | uid_set_invalid(&pfont->UID); |
2133 | | |
2134 | | /* The buildchar proc will be filled in by FAPI - |
2135 | | we won't worry about working without FAPI */ |
2136 | 2.98k | pfont->procs.encode_char = pdfi_encode_char; |
2137 | 2.98k | pfont->procs.glyph_name = ctx->get_glyph_name; |
2138 | 2.98k | pfont->procs.decode_glyph = pdfi_decode_glyph; |
2139 | 2.98k | pfont->procs.define_font = gs_no_define_font; |
2140 | 2.98k | pfont->procs.make_font = gs_no_make_font; |
2141 | 2.98k | pfont->procs.font_info = gs_default_font_info; |
2142 | 2.98k | pfont->procs.glyph_info = gs_default_glyph_info; |
2143 | 2.98k | pfont->procs.glyph_outline = pdfi_cff_glyph_outline; |
2144 | 2.98k | pfont->procs.build_char = NULL; |
2145 | 2.98k | pfont->procs.same_font = gs_default_same_font; |
2146 | 2.98k | pfont->procs.enumerate_glyph = pdfi_cff_enumerate_glyph; |
2147 | | |
2148 | 2.98k | pfont->data.procs.glyph_data = for_fdarray ? pdfi_cff_fdarray_glyph_data : pdfi_cff_glyph_data; |
2149 | 2.98k | pfont->data.procs.subr_data = pdfi_cff_subr_data; |
2150 | 2.98k | pfont->data.procs.seac_data = for_fdarray ? pdfi_cff_fdarray_seac_data : pdfi_cff_seac_data; |
2151 | 2.98k | pfont->data.procs.push_values = pdfi_cff_push; |
2152 | 2.98k | pfont->data.procs.pop_value = pdfi_cff_pop; |
2153 | 2.98k | pfont->data.interpret = gs_type2_interpret; |
2154 | 2.98k | pfont->data.lenIV = -1; |
2155 | | |
2156 | 2.98k | pfont->encoding_index = 1; /****** WRONG ******/ |
2157 | 2.98k | pfont->nearest_encoding_index = 1; /****** WRONG ******/ |
2158 | | |
2159 | 2.98k | pfont->client_data = (void *)cfffont; |
2160 | | |
2161 | 2.98k | *font = cfffont; |
2162 | 2.98k | return 0; |
2163 | 2.98k | } |
2164 | | |
2165 | | static void |
2166 | | pdfi_init_cff_font_priv(pdf_context *ctx, pdfi_gs_cff_font_priv *cffpriv, |
2167 | | byte *buf, int buflen, bool for_fdarray) |
2168 | 3.89k | { |
2169 | 3.89k | gs_matrix defmat_font = { 0.001f, 0.0f, 0.0f, 0.001f, 0.0f, 0.0f }; |
2170 | 3.89k | gs_matrix defmat_fd = { 1.00f, 0.0f, 0.0f, 1.000f, 0.0f, 0.0f }; |
2171 | 3.89k | gs_matrix *defmat = (for_fdarray ? &defmat_fd : &defmat_font); |
2172 | | |
2173 | 3.89k | memset(cffpriv, 0x00, sizeof(pdfi_gs_cff_font_priv)); |
2174 | | |
2175 | 3.89k | cffpriv->pdfcffpriv.ctx = ctx; |
2176 | 3.89k | cffpriv->pdfcffpriv.type = PDF_FONT; |
2177 | 3.89k | cffpriv->pdfcffpriv.pdfi_font_type = e_pdf_font_cff; |
2178 | | /* Dummy value for dummy object */ |
2179 | 3.89k | cffpriv->pdfcffpriv.refcnt = 0xf0f0f0f0; |
2180 | 3.89k | cffpriv->pdfcffpriv.cffdata = buf; |
2181 | 3.89k | cffpriv->pdfcffpriv.cffend = buf + buflen; |
2182 | 3.89k | cffpriv->pdfcffpriv.cidcount = 8720; |
2183 | | |
2184 | 3.89k | memcpy(&cffpriv->orig_FontMatrix, defmat, sizeof(*defmat)); |
2185 | 3.89k | memcpy(&cffpriv->FontMatrix, defmat, sizeof(*defmat)); |
2186 | 3.89k | cffpriv->next = cffpriv->prev = 0; |
2187 | 3.89k | cffpriv->memory = ctx->memory; |
2188 | 3.89k | cffpriv->dir = ctx->font_dir; |
2189 | 3.89k | cffpriv->is_resource = false; |
2190 | 3.89k | gs_notify_init(&cffpriv->notify_list, ctx->memory); |
2191 | 3.89k | cffpriv->WMode = 0; |
2192 | 3.89k | cffpriv->PaintType = 0; |
2193 | 3.89k | cffpriv->StrokeWidth = 0; |
2194 | 3.89k | cffpriv->is_cached = 0; |
2195 | 3.89k | cffpriv->FAPI = NULL; |
2196 | 3.89k | cffpriv->FAPI_font_data = NULL; |
2197 | 3.89k | cffpriv->procs.init_fstack = gs_default_init_fstack; |
2198 | 3.89k | cffpriv->procs.next_char_glyph = gs_default_next_char_glyph; |
2199 | 3.89k | cffpriv->FontType = ft_encrypted2; |
2200 | 3.89k | cffpriv->ExactSize = fbit_use_outlines; |
2201 | 3.89k | cffpriv->InBetweenSize = fbit_use_outlines; |
2202 | 3.89k | cffpriv->TransformedChar = fbit_use_outlines; |
2203 | | /* We may want to do something clever with an XUID here */ |
2204 | 3.89k | cffpriv->id = gs_next_ids(ctx->memory, 1); |
2205 | 3.89k | uid_set_invalid(&cffpriv->UID); |
2206 | | |
2207 | | |
2208 | | /* The buildchar proc will be filled in by FAPI - |
2209 | | we won't worry about working without FAPI */ |
2210 | 3.89k | cffpriv->procs.encode_char = pdfi_encode_char; |
2211 | 3.89k | cffpriv->procs.glyph_name = ctx->get_glyph_name; |
2212 | 3.89k | cffpriv->procs.decode_glyph = pdfi_decode_glyph; |
2213 | 3.89k | cffpriv->procs.define_font = gs_no_define_font; |
2214 | 3.89k | cffpriv->procs.make_font = gs_no_make_font; |
2215 | 3.89k | cffpriv->procs.font_info = gs_default_font_info; |
2216 | 3.89k | cffpriv->procs.glyph_info = gs_default_glyph_info; |
2217 | 3.89k | cffpriv->procs.glyph_outline = pdfi_cff_glyph_outline; |
2218 | 3.89k | cffpriv->procs.build_char = NULL; |
2219 | 3.89k | cffpriv->procs.same_font = gs_default_same_font; |
2220 | 3.89k | cffpriv->procs.enumerate_glyph = pdfi_cff_enumerate_glyph; |
2221 | | |
2222 | 3.89k | cffpriv->type1data.procs.glyph_data = pdfi_cff_glyph_data; |
2223 | 3.89k | cffpriv->type1data.procs.subr_data = pdfi_cff_subr_data; |
2224 | 3.89k | cffpriv->type1data.procs.seac_data = pdfi_cff_seac_data; |
2225 | 3.89k | cffpriv->type1data.procs.push_values = pdfi_cff_push; |
2226 | 3.89k | cffpriv->type1data.procs.pop_value = pdfi_cff_pop; |
2227 | 3.89k | cffpriv->type1data.interpret = gs_type2_interpret; |
2228 | 3.89k | cffpriv->type1data.lenIV = -1; |
2229 | | |
2230 | 3.89k | cffpriv->encoding_index = 1; /****** WRONG ******/ |
2231 | 3.89k | cffpriv->nearest_encoding_index = 1; /****** WRONG ******/ |
2232 | 3.89k | } |
2233 | | |
2234 | | int |
2235 | | pdfi_read_cff_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, pdf_dict *page_dict, byte *pfbuf, int64_t fbuflen, bool forcecid, pdf_font **ppdffont) |
2236 | 3.27k | { |
2237 | 3.27k | int code = 0; |
2238 | | |
2239 | 3.27k | pdf_font *ppdfont = NULL; |
2240 | 3.27k | pdf_obj *basefont = NULL; |
2241 | 3.27k | pdf_obj *tmp = NULL; |
2242 | 3.27k | pdf_obj *fontdesc = NULL; |
2243 | 3.27k | pdf_string *registry = NULL; |
2244 | 3.27k | pdf_string *ordering = NULL; |
2245 | 3.27k | byte *fbuf = pfbuf; |
2246 | | |
2247 | 3.27k | if (!memcmp(fbuf, "OTTO", 4)) { |
2248 | 157 | int i, ntables = u16(fbuf + 4); |
2249 | 157 | byte *p; |
2250 | 157 | uint32_t toffs = 0, tlen = 0; |
2251 | | |
2252 | 157 | if (ntables > 64) |
2253 | 2 | return_error(gs_error_invalidfont); |
2254 | | |
2255 | 221 | for (i = 0; i < ntables; i++) { |
2256 | 220 | p = fbuf + 12 + i * 16; |
2257 | 220 | if (p >= fbuf + fbuflen) |
2258 | 0 | break; |
2259 | | |
2260 | 220 | if (!memcmp(p, "CFF ", 4)) { |
2261 | 154 | toffs = u32(p + 8); |
2262 | 154 | tlen = u32(p + 12); |
2263 | 154 | break; |
2264 | 154 | } |
2265 | 220 | } |
2266 | 155 | if (toffs == 0 || tlen == 0 || toffs + tlen > fbuflen) { |
2267 | 21 | gs_free_object(ctx->memory, pfbuf, "pdfi_read_cff_font(fbuf)"); |
2268 | 21 | return_error(gs_error_invalidfont); |
2269 | 21 | } |
2270 | 134 | fbuf += toffs; |
2271 | 134 | fbuflen = tlen; |
2272 | 134 | } |
2273 | | |
2274 | 3.24k | if (font_dict != NULL) { |
2275 | 3.24k | code = pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc); |
2276 | 3.24k | if (code < 0) { |
2277 | 0 | fontdesc = NULL; |
2278 | 0 | } |
2279 | 3.24k | } |
2280 | 0 | else { |
2281 | 0 | fontdesc = NULL; |
2282 | 0 | } |
2283 | | |
2284 | | /* Vestigial magic number check - we can't check the third byte, as we have out of |
2285 | | spec fonts that have a head size > 4 |
2286 | | */ |
2287 | 3.24k | if (fbuf[0] == 1 && fbuf[1] == 0 && code >= 0) { |
2288 | 3.23k | pdfi_gs_cff_font_priv cffpriv; |
2289 | | |
2290 | 3.23k | pdfi_init_cff_font_priv(ctx, &cffpriv, fbuf, fbuflen, false); |
2291 | 3.23k | cffpriv.forcecid = forcecid; |
2292 | 3.23k | code = pdfi_read_cff(ctx, &cffpriv); |
2293 | | |
2294 | 3.23k | if (code >= 0) { |
2295 | 2.71k | if (cffpriv.FontType == ft_CID_encrypted) { |
2296 | 390 | pdf_obj *obj = NULL; |
2297 | 390 | pdf_cidfont_type0 *cffcid; |
2298 | 390 | gs_font_cid0 *pfont; |
2299 | | |
2300 | 390 | code = pdfi_alloc_cff_cidfont(ctx, &cffcid, font_dict->object_num); |
2301 | 390 | pfont = (gs_font_cid0 *) cffcid->pfont; |
2302 | 390 | ppdfont = (pdf_font *) cffcid; |
2303 | | |
2304 | 390 | memcpy(pfont, &cffpriv, sizeof(pdfi_gs_cff_font_common_priv)); |
2305 | 390 | memcpy(&pfont->cidata, &cffpriv.cidata, sizeof(pfont->cidata)); |
2306 | | |
2307 | 390 | pfont->procs.glyph_outline = pdfi_cff_glyph_outline; |
2308 | 390 | pfont->cidata.glyph_data = pdfi_cff_cid_glyph_data; |
2309 | | |
2310 | 390 | cffcid->orig_glyph_info = pfont->procs.glyph_info; |
2311 | 390 | pfont->procs.glyph_info = pdfi_cff_cidfont_glyph_info; |
2312 | | |
2313 | 390 | pfont->cidata.proc_data = NULL; |
2314 | 390 | pfont->FAPI = NULL; |
2315 | 390 | pfont->base = (gs_font *) cffcid->pfont; |
2316 | | |
2317 | 390 | code = pdfi_dict_knownget_type(ctx, font_dict, "CIDSystemInfo", PDF_DICT, (pdf_obj **)&obj); |
2318 | 390 | if (code <= 0) { |
2319 | 0 | cffcid->registry = cffpriv.pdfcffpriv.registry; |
2320 | 0 | cffcid->ordering = cffpriv.pdfcffpriv.ordering; |
2321 | 0 | cffcid->supplement = cffpriv.pdfcffpriv.supplement; |
2322 | 0 | } |
2323 | 390 | else { |
2324 | 390 | pdf_num *suppl = NULL; |
2325 | | |
2326 | 390 | code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Registry", PDF_STRING, (pdf_obj **)&cffcid->registry); |
2327 | 390 | if (code <= 0) { |
2328 | 0 | cffcid->registry = cffpriv.pdfcffpriv.registry; |
2329 | 0 | } |
2330 | 390 | else { |
2331 | 390 | pdfi_countdown(cffpriv.pdfcffpriv.registry); |
2332 | 390 | cffpriv.pdfcffpriv.registry = NULL; |
2333 | 390 | } |
2334 | | |
2335 | 390 | code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Ordering", PDF_STRING, (pdf_obj **)&cffcid->ordering); |
2336 | 390 | if (code <= 0) { |
2337 | 0 | cffcid->ordering = cffpriv.pdfcffpriv.ordering; |
2338 | 0 | } |
2339 | 390 | else { |
2340 | 390 | pdfi_countdown(cffpriv.pdfcffpriv.ordering); |
2341 | 390 | cffpriv.pdfcffpriv.ordering = NULL; |
2342 | 390 | } |
2343 | 390 | code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Supplement", PDF_INT, (pdf_obj **)&suppl); |
2344 | 390 | if (code <= 0 || pdfi_type_of(suppl) != PDF_INT) { |
2345 | 0 | cffcid->supplement = cffpriv.pdfcffpriv.supplement; |
2346 | 0 | } |
2347 | 390 | else { |
2348 | 390 | cffcid->supplement = suppl->value.i; |
2349 | 390 | } |
2350 | 390 | pdfi_countdown(suppl); |
2351 | 390 | } |
2352 | 390 | pdfi_countdown(obj); |
2353 | 390 | obj = NULL; |
2354 | | |
2355 | 390 | pfont->cidata.common.CIDSystemInfo.Registry.data = cffcid->registry->data; |
2356 | 390 | pfont->cidata.common.CIDSystemInfo.Registry.size = cffcid->registry->length; |
2357 | 390 | pfont->cidata.common.CIDSystemInfo.Ordering.data = cffcid->ordering->data; |
2358 | 390 | pfont->cidata.common.CIDSystemInfo.Ordering.size = cffcid->ordering->length; |
2359 | 390 | pfont->cidata.common.CIDSystemInfo.Supplement = cffcid->supplement; |
2360 | | |
2361 | 390 | cffcid->FontDescriptor = (pdf_dict *) fontdesc; |
2362 | 390 | fontdesc = NULL; |
2363 | | |
2364 | 390 | cffcid->PDF_font = font_dict; |
2365 | 390 | pdfi_countup(font_dict); |
2366 | | |
2367 | 390 | pfont->client_data = cffcid; |
2368 | | |
2369 | 390 | cffcid->object_num = font_dict->object_num; |
2370 | 390 | cffcid->generation_num = font_dict->generation_num; |
2371 | 390 | cffcid->indirect_num = font_dict->indirect_num; |
2372 | 390 | cffcid->indirect_gen = font_dict->indirect_gen; |
2373 | | |
2374 | 390 | cffcid->CharStrings = cffpriv.pdfcffpriv.CharStrings; |
2375 | 390 | cffpriv.pdfcffpriv.CharStrings = NULL; |
2376 | | |
2377 | 390 | cffcid->Subrs = cffpriv.pdfcffpriv.Subrs; |
2378 | 390 | cffcid->NumSubrs = cffpriv.pdfcffpriv.NumSubrs; |
2379 | 390 | cffpriv.pdfcffpriv.Subrs = NULL; |
2380 | | |
2381 | 390 | cffcid->GlobalSubrs = cffpriv.pdfcffpriv.GlobalSubrs; |
2382 | 390 | cffcid->NumGlobalSubrs = cffpriv.pdfcffpriv.NumGlobalSubrs; |
2383 | 390 | cffpriv.pdfcffpriv.GlobalSubrs = NULL; |
2384 | | |
2385 | 390 | cffcid->FDArray = cffpriv.pdfcffpriv.FDArray; |
2386 | 390 | cffpriv.pdfcffpriv.FDArray = NULL; |
2387 | | |
2388 | 390 | pfont->cidata.common.CIDCount = cffpriv.pdfcffpriv.cidcount; |
2389 | | |
2390 | 390 | cffcid->cidtogidmap = NULL; |
2391 | 390 | code = pdfi_dict_knownget(ctx, font_dict, "CIDToGIDMap", (pdf_obj **) &obj); |
2392 | 390 | if (code > 0) { |
2393 | | /* CIDToGIDMap can only be a stream or a name, and if it's a name |
2394 | | it's only permitted to be "/Identity", so ignore it |
2395 | | */ |
2396 | 0 | if (pdfi_type_of(obj) == PDF_STREAM) { |
2397 | 0 | byte *d; |
2398 | 0 | int64_t sz = 0; |
2399 | |
|
2400 | 0 | code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&cffcid->cidtogidmap); |
2401 | 0 | if (code < 0) { |
2402 | 0 | goto error; |
2403 | 0 | } |
2404 | 0 | pdfi_countup(cffcid->cidtogidmap); |
2405 | 0 | code = pdfi_stream_to_buffer(ctx, (pdf_stream *)obj, &d, &sz); |
2406 | 0 | if (code < 0) { |
2407 | 0 | goto error; |
2408 | 0 | } |
2409 | 0 | code = pdfi_buffer_set_data((pdf_obj *)cffcid->cidtogidmap, d, (int32_t)sz); |
2410 | 0 | if (code < 0) { |
2411 | 0 | goto error; |
2412 | 0 | } |
2413 | 0 | } |
2414 | 0 | pdfi_countdown(obj); |
2415 | 0 | obj = NULL; |
2416 | |
|
2417 | 0 | if (cffcid->cidtogidmap != NULL && cffcid->cidtogidmap->length > 0) { |
2418 | 0 | pfont->cidata.common.CIDCount = cffcid->cidtogidmap->length >> 1; |
2419 | 0 | } |
2420 | 0 | } |
2421 | 390 | pfont->cidata.common.MaxCID = pfont->cidata.common.CIDCount - 1; |
2422 | | |
2423 | 390 | code = pdfi_dict_knownget_type(ctx, font_dict, "DW", PDF_INT, (pdf_obj **) &obj); |
2424 | 390 | if (code > 0) { |
2425 | 351 | cffcid->DW = ((pdf_num *) obj)->value.i; |
2426 | 351 | pdfi_countdown(obj); |
2427 | 351 | obj = NULL; |
2428 | 351 | } |
2429 | 39 | else { |
2430 | 39 | cffcid->DW = 1000; |
2431 | 39 | } |
2432 | 390 | code = pdfi_dict_knownget_type(ctx, font_dict, "DW2", PDF_ARRAY, (pdf_obj **) &obj); |
2433 | 390 | if (code > 0) { |
2434 | 18 | cffcid->DW2 = (pdf_array *) obj; |
2435 | 18 | obj = NULL; |
2436 | 18 | } |
2437 | 372 | else { |
2438 | 372 | cffcid->DW2 = NULL; |
2439 | 372 | } |
2440 | 390 | code = pdfi_dict_knownget_type(ctx, font_dict, "W", PDF_ARRAY, (pdf_obj **) &obj); |
2441 | 390 | if (code > 0) { |
2442 | 303 | cffcid->W = (pdf_array *) obj; |
2443 | 303 | obj = NULL; |
2444 | 303 | } |
2445 | 87 | else { |
2446 | 87 | cffcid->W = NULL; |
2447 | 87 | } |
2448 | 390 | code = pdfi_dict_knownget_type(ctx, font_dict, "W2", PDF_ARRAY, (pdf_obj **) &obj); |
2449 | 390 | if (code > 0) { |
2450 | 0 | cffcid->W2 = (pdf_array *) obj; |
2451 | 0 | obj = NULL; |
2452 | 0 | } |
2453 | 390 | else { |
2454 | 390 | cffcid->W2 = NULL; |
2455 | 390 | } |
2456 | 390 | if (uid_is_XUID(&cffcid->pfont->UID)) |
2457 | 390 | uid_free(&cffcid->pfont->UID, cffcid->pfont->memory, "pdfi_read_type1_font"); |
2458 | 390 | uid_set_invalid(&cffcid->pfont->UID); |
2459 | 390 | cffcid->pfont->id = gs_next_ids(ctx->memory, 1); |
2460 | 390 | } |
2461 | 2.32k | else if (forcecid) { |
2462 | 107 | pdf_obj *obj; |
2463 | 107 | pdf_cidfont_type0 *cffcid; |
2464 | 107 | gs_font_cid0 *pfont; |
2465 | 107 | pdf_font_cff *fdcfffont; |
2466 | 107 | gs_font_type1 *pfdfont = NULL; |
2467 | 107 | static const char *const reg = "Adobe"; |
2468 | 107 | static const char *const ord = "Identity"; |
2469 | | |
2470 | 107 | code = pdfi_object_alloc(ctx, PDF_STRING, strlen(reg), (pdf_obj **) ®istry); |
2471 | 107 | if (code < 0) |
2472 | 0 | goto error; |
2473 | 107 | pdfi_countup(registry); |
2474 | | |
2475 | 107 | code = pdfi_object_alloc(ctx, PDF_STRING, strlen(ord), (pdf_obj **) &ordering); |
2476 | 107 | if (code < 0) { |
2477 | 0 | goto error; |
2478 | 0 | } |
2479 | 107 | pdfi_countup(ordering); |
2480 | | |
2481 | 107 | memcpy(registry->data, reg, strlen(reg)); |
2482 | 107 | registry->length = strlen(reg); |
2483 | 107 | memcpy(ordering->data, ord, strlen(ord)); |
2484 | 107 | ordering->length = strlen(ord); |
2485 | | |
2486 | 107 | code = pdfi_alloc_cff_font(ctx, &fdcfffont, 0, true); |
2487 | 107 | if (code < 0) |
2488 | 0 | goto error; |
2489 | | |
2490 | 107 | pfdfont = (gs_font_type1 *) fdcfffont->pfont; |
2491 | | |
2492 | 107 | code = pdfi_alloc_cff_cidfont(ctx, &cffcid, 0); |
2493 | 107 | if (code < 0) { |
2494 | 0 | gs_free_object(ctx->memory, fdcfffont, "pdfi_read_cff_font"); |
2495 | 0 | gs_free_object(ctx->memory, pfdfont, "pdfi_read_cff_font"); |
2496 | 0 | goto error; |
2497 | 0 | } |
2498 | 107 | ppdfont = (pdf_font *) cffcid; |
2499 | | |
2500 | 107 | code = pdfi_object_alloc(ctx, PDF_ARRAY, 1, (pdf_obj **) &cffcid->FDArray); |
2501 | 107 | if (code < 0) |
2502 | 0 | goto error; |
2503 | 107 | pdfi_countup(cffcid->FDArray); |
2504 | | |
2505 | 107 | pfont = (gs_font_cid0 *) cffcid->pfont; |
2506 | 107 | pfont->cidata.FDArray = (gs_font_type1 **) gs_alloc_bytes(ctx->memory, sizeof(gs_font_type1 *), "pdfi_read_cff_font"); |
2507 | 107 | pfont->base = (gs_font *)pfont; |
2508 | 107 | if (!pfont->cidata.FDArray) { |
2509 | 0 | pdfi_countdown(cffcid->FDArray); |
2510 | 0 | gs_free_object(ctx->memory, fdcfffont, "pdfi_read_cff_font"); |
2511 | 0 | gs_free_object(ctx->memory, pfdfont, "pdfi_read_cff_font"); |
2512 | 0 | gs_free_object(ctx->memory, cffcid, "pdfi_read_cff_font"); |
2513 | 0 | gs_free_object(ctx->memory, pfont, "pdfi_read_cff_font"); |
2514 | 0 | goto error; |
2515 | 0 | } |
2516 | | |
2517 | 107 | memcpy(pfdfont, &cffpriv, sizeof(pdfi_gs_cff_font_common_priv)); |
2518 | 107 | memcpy(&pfdfont->data, &cffpriv.type1data, sizeof(pfdfont->data)); |
2519 | | |
2520 | | |
2521 | 107 | pfont->procs.glyph_outline = pdfi_cff_glyph_outline; |
2522 | 107 | pfont->cidata.glyph_data = pdfi_cff_cid_glyph_data; |
2523 | 107 | pfont->cidata.common.CIDCount = cffpriv.pdfcffpriv.CharStrings->entries; |
2524 | 107 | pfont->cidata.common.MaxCID = pfont->cidata.common.CIDCount - 1; |
2525 | | |
2526 | 107 | cffcid->orig_glyph_info = pfont->procs.glyph_info; |
2527 | 107 | pfont->procs.glyph_info = pdfi_cff_cidfont_glyph_info; |
2528 | | |
2529 | 107 | pfdfont->FAPI = NULL; |
2530 | 107 | pfdfont->base = (gs_font *)pfdfont; |
2531 | 107 | pfdfont->client_data = fdcfffont; |
2532 | 107 | pdfi_array_put(ctx, cffcid->FDArray, 0, (pdf_obj *) fdcfffont); |
2533 | | |
2534 | 107 | fdcfffont->object_num = 0; |
2535 | 107 | fdcfffont->generation_num = 0; |
2536 | | |
2537 | 107 | (void)pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &basefont); |
2538 | 107 | fdcfffont->BaseFont = basefont; |
2539 | 107 | fdcfffont->Name = basefont; |
2540 | 107 | pdfi_countup(basefont); |
2541 | | |
2542 | 107 | pdfi_countdown(cffpriv.pdfcffpriv.Encoding); |
2543 | 107 | cffpriv.pdfcffpriv.Encoding = NULL; |
2544 | | |
2545 | 107 | fdcfffont->CharStrings = cffpriv.pdfcffpriv.CharStrings; |
2546 | 107 | cffpriv.pdfcffpriv.CharStrings = NULL; |
2547 | 107 | fdcfffont->Subrs = cffpriv.pdfcffpriv.Subrs; |
2548 | 107 | cffpriv.pdfcffpriv.Subrs = NULL; |
2549 | 107 | fdcfffont->NumSubrs = cffpriv.pdfcffpriv.NumSubrs; |
2550 | 107 | fdcfffont->GlobalSubrs = cffpriv.pdfcffpriv.GlobalSubrs; |
2551 | 107 | cffpriv.pdfcffpriv.GlobalSubrs = NULL; |
2552 | 107 | fdcfffont->NumGlobalSubrs = cffpriv.pdfcffpriv.NumGlobalSubrs; |
2553 | | |
2554 | 107 | cffcid->CharStrings = fdcfffont->CharStrings; |
2555 | 107 | pdfi_countup(cffcid->CharStrings); |
2556 | 107 | cffcid->Subrs = fdcfffont->Subrs; |
2557 | 107 | pdfi_countup(cffcid->Subrs); |
2558 | 107 | cffcid->GlobalSubrs = fdcfffont->GlobalSubrs; |
2559 | 107 | pdfi_countup(cffcid->GlobalSubrs); |
2560 | 107 | pdfi_countdown(fdcfffont); |
2561 | | |
2562 | 107 | cffcid->FontDescriptor = (pdf_dict *) fontdesc; |
2563 | 107 | fontdesc = NULL; |
2564 | | |
2565 | 107 | cffcid->registry = registry; |
2566 | 107 | cffcid->ordering = ordering; |
2567 | 107 | registry = ordering = NULL; |
2568 | 107 | cffcid->supplement = 0; |
2569 | | |
2570 | | /* Because we're faking a CIDFont, we want to move the scaling to the "parent" fake |
2571 | | CIDFont, and make the FDArrray use identity scaling |
2572 | | */ |
2573 | 107 | memcpy(&pfont->FontMatrix, &pfdfont->FontMatrix, sizeof(pfdfont->FontMatrix)); |
2574 | 107 | memcpy(&pfont->orig_FontMatrix, &pfdfont->orig_FontMatrix, sizeof(pfdfont->orig_FontMatrix)); |
2575 | | |
2576 | 107 | gs_make_identity(&pfdfont->FontMatrix); |
2577 | 107 | gs_make_identity(&pfdfont->orig_FontMatrix); |
2578 | | |
2579 | 107 | pfont->cidata.CIDMapOffset = 0; |
2580 | 107 | pfont->cidata.FDArray_size = 1; |
2581 | 107 | pfont->cidata.FDBytes = 0; |
2582 | 107 | pfont->cidata.glyph_data = pdfi_cff_cid_glyph_data; |
2583 | 107 | pfont->cidata.FDArray[0] = pfdfont; |
2584 | 107 | pfont->cidata.common.CIDSystemInfo.Registry.data = cffcid->registry->data; |
2585 | 107 | pfont->cidata.common.CIDSystemInfo.Registry.size = cffcid->registry->length; |
2586 | 107 | pfont->cidata.common.CIDSystemInfo.Ordering.data = cffcid->ordering->data; |
2587 | 107 | pfont->cidata.common.CIDSystemInfo.Ordering.size = cffcid->ordering->length; |
2588 | 107 | pfont->cidata.common.CIDSystemInfo.Supplement = cffcid->supplement; |
2589 | 107 | pfont->client_data = cffcid; |
2590 | | |
2591 | 107 | cffcid->object_num = font_dict->object_num; |
2592 | 107 | cffcid->generation_num = font_dict->generation_num; |
2593 | 107 | cffcid->indirect_num = font_dict->indirect_num; |
2594 | 107 | cffcid->indirect_gen = font_dict->indirect_gen; |
2595 | | |
2596 | 107 | cffcid->PDF_font = font_dict; |
2597 | 107 | pdfi_countup(font_dict); |
2598 | | |
2599 | 107 | cffcid->cidtogidmap = NULL; |
2600 | 107 | code = pdfi_dict_knownget(ctx, font_dict, "CIDToGIDMap", (pdf_obj **) &obj); |
2601 | 107 | if (code > 0) { |
2602 | 59 | byte *d; |
2603 | 59 | int64_t sz = 0; |
2604 | | /* CIDToGIDMap can only be a stream or a name, and if it's a name |
2605 | | it's only permitted to be "/Identity", so ignore it |
2606 | | */ |
2607 | 59 | if (pdfi_type_of(obj) == PDF_STREAM) { |
2608 | 5 | code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&cffcid->cidtogidmap); |
2609 | 5 | if (code < 0) { |
2610 | 0 | goto error; |
2611 | 0 | } |
2612 | 5 | pdfi_countup(cffcid->cidtogidmap); |
2613 | 5 | code = pdfi_stream_to_buffer(ctx, (pdf_stream *)obj, &d, &sz); |
2614 | 5 | if (code < 0) { |
2615 | 0 | goto error; |
2616 | 0 | } |
2617 | 5 | code = pdfi_buffer_set_data((pdf_obj *)cffcid->cidtogidmap, d, (int32_t)sz); |
2618 | 5 | if (code < 0) { |
2619 | 0 | goto error; |
2620 | 0 | } |
2621 | 5 | } |
2622 | 59 | pdfi_countdown(obj); |
2623 | 59 | obj = NULL; |
2624 | | |
2625 | 59 | if (cffcid->cidtogidmap != NULL && cffcid->cidtogidmap->length > 0) { |
2626 | 5 | pfont->cidata.common.CIDCount = cffcid->cidtogidmap->length >> 1; |
2627 | 5 | } |
2628 | 59 | } |
2629 | 107 | pfont->cidata.common.MaxCID = pfont->cidata.common.CIDCount - 1; |
2630 | | |
2631 | 107 | code = pdfi_dict_knownget_type(ctx, font_dict, "DW", PDF_INT, (pdf_obj **) &obj); |
2632 | 107 | if (code > 0) { |
2633 | 73 | cffcid->DW = ((pdf_num *) obj)->value.i; |
2634 | 73 | pdfi_countdown(obj); |
2635 | 73 | obj = NULL; |
2636 | 73 | } |
2637 | 34 | else { |
2638 | 34 | cffcid->DW = 1000; |
2639 | 34 | } |
2640 | 107 | code = pdfi_dict_knownget_type(ctx, font_dict, "DW2", PDF_ARRAY, (pdf_obj **) &obj); |
2641 | 107 | if (code > 0) { |
2642 | 0 | cffcid->DW2 = (pdf_array *) obj; |
2643 | 0 | obj = NULL; |
2644 | 0 | } |
2645 | 107 | else { |
2646 | 107 | cffcid->DW2 = NULL; |
2647 | 107 | } |
2648 | 107 | code = pdfi_dict_knownget_type(ctx, font_dict, "W", PDF_ARRAY, (pdf_obj **) &obj); |
2649 | 107 | if (code > 0) { |
2650 | 107 | cffcid->W = (pdf_array *) obj; |
2651 | 107 | obj = NULL; |
2652 | 107 | } |
2653 | 0 | else { |
2654 | 0 | cffcid->W = NULL; |
2655 | 0 | } |
2656 | 107 | code = pdfi_dict_knownget_type(ctx, font_dict, "W2", PDF_ARRAY, (pdf_obj **) &obj); |
2657 | 107 | if (code > 0) { |
2658 | 0 | cffcid->W2 = (pdf_array *) obj; |
2659 | 0 | obj = NULL; |
2660 | 0 | } |
2661 | 107 | else { |
2662 | 107 | cffcid->W2 = NULL; |
2663 | 107 | } |
2664 | | |
2665 | 107 | if (uid_is_XUID(&cffcid->pfont->UID)) |
2666 | 107 | uid_free(&cffcid->pfont->UID, cffcid->pfont->memory, "pdfi_read_type1_font"); |
2667 | 107 | uid_set_invalid(&cffcid->pfont->UID); |
2668 | 107 | cffcid->pfont->id = gs_next_ids(ctx->memory, 1); |
2669 | 107 | } |
2670 | 2.22k | else { |
2671 | 2.22k | pdf_font_cff *cfffont; |
2672 | 2.22k | gs_font_type1 *pfont = NULL; |
2673 | 2.22k | pdf_obj *tounicode = NULL; |
2674 | | |
2675 | 2.22k | code = pdfi_alloc_cff_font(ctx, &cfffont, font_dict != NULL ? font_dict->object_num : 0, false); |
2676 | 2.22k | pfont = (gs_font_type1 *) cfffont->pfont; |
2677 | 2.22k | ppdfont = (pdf_font *) cfffont; |
2678 | | |
2679 | 2.22k | memcpy(pfont, &cffpriv, sizeof(pdfi_gs_cff_font_common_priv)); |
2680 | 2.22k | memcpy(&pfont->data, &cffpriv.type1data, sizeof(pfont->data)); |
2681 | 2.22k | pfont->FAPI = NULL; |
2682 | 2.22k | pfont->client_data = cfffont; |
2683 | 2.22k | pfont->base = (gs_font *) cfffont->pfont; |
2684 | | |
2685 | 2.22k | pfont->procs.glyph_info = pdfi_cff_glyph_info; |
2686 | | |
2687 | 2.22k | if (font_dict) { |
2688 | 2.22k | cfffont->object_num = font_dict->object_num; |
2689 | 2.22k | cfffont->generation_num = font_dict->generation_num; |
2690 | 2.22k | cfffont->indirect_num = font_dict->indirect_num; |
2691 | 2.22k | cfffont->indirect_gen = font_dict->indirect_gen; |
2692 | | |
2693 | 2.22k | (void)pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &basefont); |
2694 | 2.22k | } |
2695 | | |
2696 | 2.22k | cfffont->BaseFont = basefont; |
2697 | 2.22k | cfffont->Name = basefont; |
2698 | 2.22k | pdfi_countup(basefont); |
2699 | | |
2700 | 2.22k | cfffont->CharStrings = cffpriv.pdfcffpriv.CharStrings; |
2701 | 2.22k | cffpriv.pdfcffpriv.CharStrings = NULL; |
2702 | | |
2703 | 2.22k | cfffont->Subrs = cffpriv.pdfcffpriv.Subrs; |
2704 | 2.22k | cfffont->NumSubrs = cffpriv.pdfcffpriv.NumSubrs; |
2705 | 2.22k | cffpriv.pdfcffpriv.Subrs = NULL; |
2706 | | |
2707 | 2.22k | cfffont->GlobalSubrs = cffpriv.pdfcffpriv.GlobalSubrs; |
2708 | 2.22k | cfffont->NumGlobalSubrs = cffpriv.pdfcffpriv.NumGlobalSubrs; |
2709 | 2.22k | cffpriv.pdfcffpriv.GlobalSubrs = NULL; |
2710 | | |
2711 | 2.22k | cfffont->FontDescriptor = (pdf_dict *) fontdesc; |
2712 | 2.22k | fontdesc = NULL; |
2713 | | |
2714 | 2.22k | cfffont->PDF_font = font_dict; |
2715 | 2.22k | pdfi_countup(font_dict); |
2716 | | |
2717 | 2.22k | cfffont->descflags = 0; |
2718 | 2.22k | if (cfffont->FontDescriptor != NULL) { |
2719 | 2.22k | code = pdfi_dict_get_int(ctx, cfffont->FontDescriptor, "Flags", &cfffont->descflags); |
2720 | 2.22k | if (code >= 0) { |
2721 | | /* If both the symbolic and non-symbolic flag are set, |
2722 | | believe that latter. |
2723 | | */ |
2724 | 2.22k | if ((cfffont->descflags & 32) != 0) |
2725 | 1.14k | cfffont->descflags = (cfffont->descflags & ~4); |
2726 | 2.22k | } |
2727 | 2.22k | } |
2728 | | /* ZapfDingbats and Symbol we just have to know are symbolic */ |
2729 | 2.22k | if (pdfi_font_known_symbolic(basefont)) { |
2730 | 0 | cfffont->descflags |= 4; |
2731 | 0 | } |
2732 | | |
2733 | 2.22k | pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)cfffont); |
2734 | | |
2735 | | /* Widths are defined assuming a 1000x1000 design grid, but we apply |
2736 | | * them in font space - so undo the 1000x1000 scaling, and apply |
2737 | | * the inverse of the font's x scaling |
2738 | | */ |
2739 | 2.22k | if (font_dict != NULL) { |
2740 | | /* ignore errors with widths... for now */ |
2741 | 2.22k | (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font*)cfffont, (double)(0.001 / hypot(pfont->FontMatrix.xx, pfont->FontMatrix.xy))); |
2742 | 2.22k | } |
2743 | | |
2744 | 2.22k | if (font_dict != NULL) |
2745 | 2.22k | code = pdfi_dict_knownget(ctx, font_dict, "Encoding", &tmp); |
2746 | 0 | else |
2747 | 0 | code = gs_error_undefined; |
2748 | 2.22k | if (code == 1) { |
2749 | 2.14k | if ((cfffont->descflags & 4) != 0 && pdfi_type_of(tmp) == PDF_DICT) { |
2750 | 770 | code = pdfi_create_Encoding(ctx, tmp, (pdf_obj *)cffpriv.pdfcffpriv.Encoding, (pdf_obj **) &cfffont->Encoding); |
2751 | 770 | if (code >= 0) { |
2752 | 770 | pdfi_countdown(cffpriv.pdfcffpriv.Encoding); |
2753 | 770 | cffpriv.pdfcffpriv.Encoding = NULL; |
2754 | 770 | code = 1; |
2755 | 770 | } |
2756 | 770 | } |
2757 | 1.37k | else if ((pdfi_type_of(tmp) == PDF_NAME || pdfi_type_of(tmp) == PDF_DICT)) { |
2758 | 1.37k | code = pdfi_create_Encoding(ctx, tmp, NULL, (pdf_obj **) &cfffont->Encoding); |
2759 | 1.37k | if (code >= 0) { |
2760 | 1.36k | pdfi_countdown(cffpriv.pdfcffpriv.Encoding); |
2761 | 1.36k | cffpriv.pdfcffpriv.Encoding = NULL; |
2762 | 1.36k | code = 1; |
2763 | 1.36k | } |
2764 | 1.37k | } |
2765 | 1 | else |
2766 | 1 | code = gs_error_undefined; |
2767 | | |
2768 | 2.14k | if (code == 1) { |
2769 | 2.13k | } |
2770 | 2.14k | pdfi_countdown(tmp); |
2771 | 2.14k | tmp = NULL; |
2772 | 2.14k | } |
2773 | 79 | else { |
2774 | 79 | pdfi_countdown(tmp); |
2775 | 79 | tmp = NULL; |
2776 | 79 | code = 0; |
2777 | 79 | } |
2778 | 2.22k | if (code <= 0) { |
2779 | 82 | cfffont->Encoding = cffpriv.pdfcffpriv.Encoding; |
2780 | 82 | cffpriv.pdfcffpriv.Encoding = NULL; |
2781 | 82 | } |
2782 | | |
2783 | | /* Since the underlying font stream can be shared between font descriptors, |
2784 | | and the font descriptors can be shared between font objects, if we change |
2785 | | the encoding, we can't share cached glyphs with other instances of this |
2786 | | underlying font, so invalidate the UniqueID/XUID so the glyph cache won't |
2787 | | try. |
2788 | | */ |
2789 | 2.22k | if (uid_is_XUID(&cfffont->pfont->UID)) |
2790 | 2.22k | uid_free(&cfffont->pfont->UID, cfffont->pfont->memory, "pdfi_read_type1_font"); |
2791 | 2.22k | uid_set_invalid(&cfffont->pfont->UID); |
2792 | 2.22k | cfffont->pfont->id = gs_next_ids(ctx->memory, 1); |
2793 | | |
2794 | 2.22k | if (ctx->args.ignoretounicode != true && font_dict != NULL) { |
2795 | 2.22k | code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tounicode); |
2796 | 2.22k | if (code >= 0 && pdfi_type_of(tounicode) == PDF_STREAM) { |
2797 | 610 | pdf_cmap *tu = NULL; |
2798 | 610 | code = pdfi_read_cmap(ctx, tounicode, &tu); |
2799 | 610 | pdfi_countdown(tounicode); |
2800 | 610 | tounicode = (pdf_obj *)tu; |
2801 | 610 | } |
2802 | 2.22k | if (code < 0 || (tounicode != NULL && pdfi_type_of(tounicode) != PDF_CMAP)) { |
2803 | 1.61k | pdfi_countdown(tounicode); |
2804 | 1.61k | tounicode = NULL; |
2805 | 1.61k | code = 0; |
2806 | 1.61k | } |
2807 | 2.22k | } |
2808 | 0 | else { |
2809 | 0 | tounicode = NULL; |
2810 | 0 | } |
2811 | 2.22k | cfffont->ToUnicode = tounicode; |
2812 | 2.22k | tounicode = NULL; |
2813 | 2.22k | } |
2814 | 2.71k | } |
2815 | 3.23k | error: |
2816 | 3.23k | if (code < 0) { |
2817 | 518 | pdfi_countdown(cffpriv.pdfcffpriv.Subrs); |
2818 | 518 | pdfi_countdown(cffpriv.pdfcffpriv.GlobalSubrs); |
2819 | 518 | pdfi_countdown(cffpriv.pdfcffpriv.CharStrings); |
2820 | 518 | pdfi_countdown(cffpriv.pdfcffpriv.CIDSystemInfo); |
2821 | 518 | pdfi_countdown(cffpriv.pdfcffpriv.W); |
2822 | 518 | pdfi_countdown(cffpriv.pdfcffpriv.DW2); |
2823 | 518 | pdfi_countdown(cffpriv.pdfcffpriv.W2); |
2824 | 518 | pdfi_countdown(cffpriv.pdfcffpriv.FDArray); |
2825 | 518 | pdfi_countdown(cffpriv.pdfcffpriv.registry); |
2826 | 518 | pdfi_countdown(cffpriv.pdfcffpriv.ordering); |
2827 | 518 | pdfi_countdown(cffpriv.pdfcffpriv.Encoding); |
2828 | 518 | if (cffpriv.FontType == ft_CID_encrypted) { |
2829 | 48 | gs_free_object(ctx->memory, cffpriv.cidata.FDArray, "pdfi_read_cff_font(gs_font FDArray, error)"); |
2830 | 48 | } |
2831 | 518 | } |
2832 | 2.71k | else { |
2833 | 2.71k | code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, ppdfont->pfont); |
2834 | 2.71k | if (code < 0) { |
2835 | 0 | goto error; |
2836 | 0 | } |
2837 | | |
2838 | 2.71k | code = gs_definefont(ctx->font_dir, (gs_font *) ppdfont->pfont); |
2839 | | |
2840 | 2.71k | if (code >= 0) |
2841 | 2.71k | code = pdfi_fapi_passfont((pdf_font *) ppdfont, 0, NULL, NULL, NULL, 0); |
2842 | | |
2843 | | /* object_num can be zero if the dictionary was defined inline */ |
2844 | 2.71k | if (code >= 0 && ppdfont->object_num != 0) { |
2845 | 2.51k | (void)replace_cache_entry(ctx, (pdf_obj *) ppdfont); |
2846 | 2.51k | } |
2847 | | |
2848 | 2.71k | if (code >= 0) { |
2849 | 2.70k | *ppdffont = (pdf_font *) ppdfont; |
2850 | 2.70k | ppdfont = NULL; |
2851 | 2.70k | } |
2852 | 2.71k | } |
2853 | 3.23k | } |
2854 | 3.24k | gs_free_object(ctx->memory, pfbuf, "pdfi_read_cff_font(fbuf)"); |
2855 | 3.24k | pdfi_countdown(ppdfont); |
2856 | 3.24k | pdfi_countdown(fontdesc); |
2857 | 3.24k | pdfi_countdown(ordering); |
2858 | 3.24k | pdfi_countdown(registry); |
2859 | | |
2860 | 3.24k | if (code < 0) { |
2861 | 529 | *ppdffont = NULL; |
2862 | 529 | return_error(gs_error_invalidfont); |
2863 | 529 | } |
2864 | | |
2865 | 2.71k | return code; |
2866 | 3.24k | } |
2867 | | |
2868 | | int |
2869 | | pdfi_read_type1C_font(pdf_context *ctx, pdf_dict *font_dict, |
2870 | | pdf_dict *stream_dict, pdf_dict *page_dict, pdf_font **ppdffont) |
2871 | 0 | { |
2872 | 0 | int code; |
2873 | 0 | pdf_obj *fontdesc = NULL; |
2874 | 0 | pdf_obj *fontfile = NULL; |
2875 | 0 | byte *fbuf; |
2876 | 0 | int64_t fbuflen = 0; |
2877 | |
|
2878 | 0 | code = pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc); |
2879 | |
|
2880 | 0 | if (code >=0 && fontdesc != NULL) { |
2881 | 0 | code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile", PDF_STREAM, &fontfile); |
2882 | |
|
2883 | 0 | if (code < 0) |
2884 | 0 | code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile2", PDF_STREAM, &fontfile); |
2885 | |
|
2886 | 0 | if (code < 0) |
2887 | 0 | code = pdfi_dict_get_type(ctx, (pdf_dict *) fontdesc, "FontFile3", PDF_STREAM, &fontfile); |
2888 | 0 | } |
2889 | 0 | pdfi_countdown(fontdesc); |
2890 | |
|
2891 | 0 | if (code >= 0 && fontfile != NULL) { |
2892 | 0 | code = pdfi_stream_to_buffer(ctx, (pdf_stream *) fontfile, &fbuf, &fbuflen); |
2893 | 0 | pdfi_countdown(fontfile); |
2894 | 0 | } |
2895 | 0 | else { |
2896 | | /* TODO - handle non-emebedded case */ |
2897 | 0 | return_error(gs_error_invalidfont); |
2898 | 0 | } |
2899 | | |
2900 | 0 | code = pdfi_read_cff_font(ctx, stream_dict, page_dict, font_dict, fbuf, fbuflen, false, ppdffont); |
2901 | |
|
2902 | 0 | return code; |
2903 | 0 | } |
2904 | | |
2905 | | int |
2906 | | pdfi_copy_cff_font(pdf_context *ctx, pdf_font *spdffont, pdf_dict *font_dict, pdf_font **tpdffont) |
2907 | 0 | { |
2908 | 0 | int code = 0; |
2909 | 0 | pdf_font_cff *font = NULL; |
2910 | 0 | gs_font_type1 *spfont1 = (gs_font_type1 *) spdffont->pfont; |
2911 | 0 | gs_font_type1 *dpfont1; |
2912 | 0 | gs_id t_id; |
2913 | 0 | pdf_obj *tmp; |
2914 | |
|
2915 | 0 | if (font_dict == NULL) |
2916 | 0 | return_error(gs_error_invalidfont); |
2917 | | |
2918 | 0 | code = pdfi_alloc_cff_font(ctx, &font, font_dict->object_num, false); |
2919 | 0 | if (code < 0) |
2920 | 0 | return code; |
2921 | 0 | dpfont1 = (gs_font_type1 *) font->pfont; |
2922 | |
|
2923 | 0 | t_id = dpfont1->id; |
2924 | 0 | memcpy(dpfont1, spfont1, sizeof(gs_font_type1)); |
2925 | 0 | dpfont1->id = t_id; |
2926 | 0 | dpfont1->FAPI = NULL; |
2927 | 0 | dpfont1->FAPI_font_data = NULL; |
2928 | 0 | dpfont1->notify_list.memory = NULL; |
2929 | 0 | dpfont1->notify_list.first = NULL; |
2930 | 0 | gs_notify_init(&dpfont1->notify_list, dpfont1->memory); |
2931 | |
|
2932 | 0 | memcpy(font, spdffont, sizeof(pdf_font_type1)); |
2933 | 0 | font->refcnt = 1; |
2934 | 0 | font->pfont = (gs_font_base *)dpfont1; |
2935 | 0 | dpfont1->client_data = (void *)font; |
2936 | 0 | font->filename = NULL; |
2937 | |
|
2938 | 0 | font->PDF_font = font_dict; |
2939 | 0 | font->object_num = font_dict->object_num; |
2940 | 0 | font->generation_num = font_dict->generation_num; |
2941 | 0 | pdfi_countup(font->PDF_font); |
2942 | | |
2943 | | /* We want basefont and descriptor, but we can live without them */ |
2944 | 0 | font->BaseFont = NULL; |
2945 | 0 | (void)pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, &font->BaseFont); |
2946 | 0 | font->FontDescriptor = NULL; |
2947 | 0 | (void)pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, (pdf_obj **)&font->FontDescriptor); |
2948 | |
|
2949 | 0 | pdfi_countup(font->Name); |
2950 | 0 | pdfi_countup(font->CharStrings); |
2951 | 0 | pdfi_countup(font->Subrs); |
2952 | 0 | pdfi_countup(font->GlobalSubrs); |
2953 | |
|
2954 | 0 | if (font->BaseFont != NULL && ((pdf_name *)font->BaseFont)->length <= gs_font_name_max) { |
2955 | 0 | memcpy(dpfont1->key_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length); |
2956 | 0 | dpfont1->key_name.size = ((pdf_name *)font->BaseFont)->length; |
2957 | 0 | memcpy(dpfont1->font_name.chars, ((pdf_name *)font->BaseFont)->data, ((pdf_name *)font->BaseFont)->length); |
2958 | 0 | dpfont1->font_name.size = ((pdf_name *)font->BaseFont)->length; |
2959 | 0 | } |
2960 | |
|
2961 | 0 | font->Encoding = NULL; |
2962 | 0 | font->ToUnicode = NULL; |
2963 | 0 | font->Widths = NULL; |
2964 | |
|
2965 | 0 | pdfi_font_set_first_last_char(ctx, font_dict, (pdf_font *)font); |
2966 | 0 | (void)pdfi_font_create_widths(ctx, font_dict, (pdf_font *)font, (double)(0.001 / hypot(dpfont1->FontMatrix.xx, dpfont1->FontMatrix.xy))); |
2967 | |
|
2968 | 0 | font->descflags = 0; |
2969 | 0 | if (font->FontDescriptor != NULL) { |
2970 | 0 | code = pdfi_dict_get_int(ctx, font->FontDescriptor, "Flags", &font->descflags); |
2971 | 0 | if (code >= 0) { |
2972 | | /* If both the symbolic and non-symbolic flag are set, |
2973 | | believe that latter. |
2974 | | */ |
2975 | 0 | if ((font->descflags & 32) != 0) |
2976 | 0 | font->descflags = (font->descflags & ~4); |
2977 | 0 | } |
2978 | 0 | } |
2979 | |
|
2980 | 0 | if (pdfi_font_known_symbolic(font->BaseFont)) { |
2981 | 0 | font->descflags |= 4; |
2982 | 0 | } |
2983 | | |
2984 | |
|
2985 | 0 | tmp = NULL; |
2986 | 0 | code = pdfi_dict_knownget(ctx, font_dict, "Encoding", &tmp); |
2987 | 0 | if (code == 1) { |
2988 | 0 | if ((pdfi_type_of(tmp) == PDF_NAME || pdfi_type_of(tmp) == PDF_DICT) && (font->descflags & 4) == 0) { |
2989 | 0 | code = pdfi_create_Encoding(ctx, tmp, NULL, (pdf_obj **) & font->Encoding); |
2990 | 0 | if (code >= 0) |
2991 | 0 | code = 1; |
2992 | 0 | } |
2993 | 0 | else if (pdfi_type_of(tmp) == PDF_DICT && (font->descflags & 4) != 0) { |
2994 | 0 | code = pdfi_create_Encoding(ctx, tmp, (pdf_obj *)spdffont->Encoding, (pdf_obj **) &font->Encoding); |
2995 | 0 | if (code >= 0) |
2996 | 0 | code = 1; |
2997 | 0 | } |
2998 | 0 | else |
2999 | 0 | code = gs_error_undefined; |
3000 | 0 | pdfi_countdown(tmp); |
3001 | 0 | tmp = NULL; |
3002 | 0 | } |
3003 | 0 | else { |
3004 | 0 | pdfi_countdown(tmp); |
3005 | 0 | tmp = NULL; |
3006 | 0 | code = 0; |
3007 | 0 | } |
3008 | |
|
3009 | 0 | if (code <= 0) { |
3010 | 0 | font->Encoding = spdffont->Encoding; |
3011 | 0 | pdfi_countup(font->Encoding); |
3012 | 0 | } |
3013 | | |
3014 | | /* Since various aspects of the font may differ (widths, encoding, etc) |
3015 | | we cannot reliably use the UniqueID/XUID for copied fonts. |
3016 | | */ |
3017 | 0 | if (uid_is_XUID(&font->pfont->UID)) |
3018 | 0 | uid_free(&font->pfont->UID, font->pfont->memory, "pdfi_read_type1_font"); |
3019 | 0 | uid_set_invalid(&font->pfont->UID); |
3020 | |
|
3021 | 0 | code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, font->pfont); |
3022 | 0 | if (code < 0) { |
3023 | 0 | goto error; |
3024 | 0 | } |
3025 | | |
3026 | 0 | if (ctx->args.ignoretounicode != true) { |
3027 | 0 | code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tmp); |
3028 | 0 | if (code >= 0 && pdfi_type_of(tmp) == PDF_STREAM) { |
3029 | 0 | pdf_cmap *tu = NULL; |
3030 | 0 | code = pdfi_read_cmap(ctx, tmp, &tu); |
3031 | 0 | pdfi_countdown(tmp); |
3032 | 0 | tmp = (pdf_obj *)tu; |
3033 | 0 | } |
3034 | 0 | if (code < 0 || (tmp != NULL && pdfi_type_of(tmp) != PDF_CMAP)) { |
3035 | 0 | pdfi_countdown(tmp); |
3036 | 0 | tmp = NULL; |
3037 | 0 | code = 0; |
3038 | 0 | } |
3039 | 0 | } |
3040 | 0 | else { |
3041 | 0 | tmp = NULL; |
3042 | 0 | } |
3043 | 0 | font->ToUnicode = tmp; |
3044 | |
|
3045 | 0 | code = gs_definefont(ctx->font_dir, (gs_font *) font->pfont); |
3046 | 0 | if (code < 0) { |
3047 | 0 | goto error; |
3048 | 0 | } |
3049 | | |
3050 | 0 | code = pdfi_fapi_passfont((pdf_font *) font, 0, NULL, NULL, NULL, 0); |
3051 | 0 | if (code < 0) { |
3052 | 0 | goto error; |
3053 | 0 | } |
3054 | | /* object_num can be zero if the dictionary was defined inline */ |
3055 | 0 | if (font->object_num != 0) { |
3056 | 0 | (void)replace_cache_entry(ctx, (pdf_obj *) font); |
3057 | 0 | } |
3058 | |
|
3059 | 0 | *tpdffont = (pdf_font *)font; |
3060 | |
|
3061 | 0 | error: |
3062 | 0 | if (code < 0) |
3063 | 0 | pdfi_countdown(font); |
3064 | 0 | return code; |
3065 | 0 | } |
3066 | | |
3067 | | int |
3068 | | pdfi_free_font_cff(pdf_obj *font) |
3069 | 2.98k | { |
3070 | 2.98k | pdf_font_cff *pdfontcff = (pdf_font_cff *) font; |
3071 | | |
3072 | 2.98k | gs_free_object(OBJ_MEMORY(font), pdfontcff->pfont, "pdfi_free_font_cff(pfont)"); |
3073 | | |
3074 | 2.98k | pdfi_countdown(pdfontcff->PDF_font); |
3075 | 2.98k | pdfi_countdown(pdfontcff->BaseFont); |
3076 | 2.98k | pdfi_countdown(pdfontcff->Name); |
3077 | 2.98k | pdfi_countdown(pdfontcff->FontDescriptor); |
3078 | 2.98k | pdfi_countdown(pdfontcff->CharStrings); |
3079 | 2.98k | pdfi_countdown(pdfontcff->Subrs); |
3080 | 2.98k | pdfi_countdown(pdfontcff->GlobalSubrs); |
3081 | 2.98k | pdfi_countdown(pdfontcff->Encoding); |
3082 | 2.98k | pdfi_countdown(pdfontcff->ToUnicode); |
3083 | 2.98k | pdfi_countdown(pdfontcff->filename); |
3084 | | |
3085 | 2.98k | gs_free_object(OBJ_MEMORY(font), pdfontcff->Widths, "Type 2 fontWidths"); |
3086 | 2.98k | gs_free_object(OBJ_MEMORY(font), pdfontcff, "pdfi_free_font_cff(pbfont)"); |
3087 | | |
3088 | 2.98k | return 0; |
3089 | 2.98k | } |
3090 | | |
3091 | | int |
3092 | | pdfi_free_font_cidtype0(pdf_obj *font) |
3093 | 497 | { |
3094 | 497 | pdf_cidfont_type0 *pdfont0 = (pdf_cidfont_type0 *) font; |
3095 | 497 | gs_font_cid0 *pfont = (gs_font_cid0 *) pdfont0->pfont; |
3096 | | |
3097 | | /* Only have to free the FDArray memory here. Each gs_font in the array is |
3098 | | referenced by a pdfi font, reference by pdfont0->FDArray. Freeing that |
3099 | | array will free each pdfi font, freeing the pdfi font will free the gs_font. |
3100 | | gs_fonts are not reference counted |
3101 | | */ |
3102 | 497 | gs_free_object(OBJ_MEMORY(font), pfont->cidata.FDArray, "pdfi_free_font_cidtype0(pfont->fdarray)"); |
3103 | 497 | gs_free_object(OBJ_MEMORY(font), pdfont0->pfont, "pdfi_free_font_cff(pfont)"); |
3104 | | |
3105 | 497 | pdfi_countdown(pdfont0->PDF_font); |
3106 | 497 | pdfi_countdown(pdfont0->BaseFont); |
3107 | 497 | pdfi_countdown(pdfont0->FontDescriptor); |
3108 | 497 | pdfi_countdown(pdfont0->CharStrings); |
3109 | 497 | pdfi_countdown(pdfont0->Subrs); |
3110 | 497 | pdfi_countdown(pdfont0->GlobalSubrs); |
3111 | 497 | pdfi_countdown(pdfont0->CIDSystemInfo); |
3112 | 497 | pdfi_countdown(pdfont0->W); |
3113 | 497 | pdfi_countdown(pdfont0->DW2); |
3114 | 497 | pdfi_countdown(pdfont0->W2); |
3115 | 497 | pdfi_countdown(pdfont0->FDArray); |
3116 | 497 | pdfi_countdown(pdfont0->registry); |
3117 | 497 | pdfi_countdown(pdfont0->ordering); |
3118 | 497 | pdfi_countdown(pdfont0->cidtogidmap); |
3119 | 497 | pdfi_countdown(pdfont0->filename); |
3120 | | |
3121 | 497 | gs_free_object(OBJ_MEMORY(font), pdfont0, "pdfi_free_font_cff(pbfont)"); |
3122 | | |
3123 | 497 | return 0; |
3124 | 497 | } |