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