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