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