/src/ghostpdl/pdf/pdf_font11.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2020-2025 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | /* code for CIDFontType2/Type 9 font handling */ |
17 | | /* CIDFonts with Truetype outlines */ |
18 | | |
19 | | #include "pdf_int.h" |
20 | | #include "pdf_font.h" |
21 | | #include "pdf_font0.h" |
22 | | #include "pdf_fontTT.h" |
23 | | #include "pdf_font_types.h" |
24 | | #include "pdf_stack.h" |
25 | | #include "pdf_file.h" |
26 | | #include "pdf_dict.h" |
27 | | #include "pdf_array.h" |
28 | | #include "pdf_deref.h" |
29 | | #include "gxfont42.h" |
30 | | #include "gxfcid.h" |
31 | | #include "gsutil.h" /* For gs_next_ids() */ |
32 | | |
33 | | static int pdfi_cidtype2_string_proc(gs_font_type42 * pfont, ulong offset, uint length, |
34 | | const byte ** pdata) |
35 | 404M | { |
36 | 404M | pdf_cidfont_type2 *ttfont = (pdf_cidfont_type2 *)pfont->client_data; |
37 | 404M | int code = 0; |
38 | | |
39 | 404M | if (offset + length > ttfont->sfnt->length) { |
40 | 4.02M | *pdata = NULL; |
41 | 4.02M | code = gs_note_error(gs_error_invalidfont); |
42 | 4.02M | } |
43 | 400M | else { |
44 | 400M | *pdata = ttfont->sfnt->data + offset; |
45 | 400M | } |
46 | 404M | return code; |
47 | 404M | } |
48 | | |
49 | | static int pdfi_cidtype2_CIDMap_proc(gs_font_cid2 *pfont, gs_glyph glyph) |
50 | 814k | { |
51 | 814k | pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)pfont->client_data; |
52 | 814k | uint gid = glyph - GS_MIN_CID_GLYPH; |
53 | 814k | int code = 0; |
54 | | |
55 | 814k | if (pdffont11->substitute == true) { |
56 | 409k | unsigned int ucc = 0; |
57 | 409k | int code = pfont->procs.decode_glyph((gs_font *)pfont, glyph, -1, NULL, 0); |
58 | 409k | if (code == 2) { |
59 | 2.68k | uchar sccode[2] = {0}; |
60 | 2.68k | (void)pfont->procs.decode_glyph((gs_font *)pfont, glyph, -1, (ushort *)&sccode, 2); |
61 | 2.68k | ucc = (sccode[0] << 8) + sccode[1]; |
62 | 2.68k | } |
63 | 406k | else if (code == 4) { |
64 | 0 | uchar iccode[4] = {0}; |
65 | 0 | (void)pfont->procs.decode_glyph((gs_font *)pfont, glyph, -1, (ushort *)&iccode, 2); |
66 | 0 | ucc = (iccode[0] << 24) + (iccode[1] << 16) + (iccode[2] << 8) + iccode[3]; |
67 | |
|
68 | 0 | } |
69 | 409k | if (code == 2 || code == 4) { |
70 | 2.68k | code = pdfi_fapi_check_cmap_for_GID((gs_font *)pfont, (unsigned int)ucc, &gid); |
71 | 2.68k | if (code < 0 || gid == 0) |
72 | 3 | gid = glyph - GS_MIN_CID_GLYPH; |
73 | 2.68k | } |
74 | 409k | } |
75 | | |
76 | 814k | if (code == 0 && pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > (gid << 1) + 1) { |
77 | 415k | gid = pdffont11->cidtogidmap->data[gid << 1] << 8 | pdffont11->cidtogidmap->data[(gid << 1) + 1]; |
78 | 415k | } |
79 | | |
80 | 814k | return (int)gid; |
81 | 814k | } |
82 | | |
83 | | static uint pdfi_cidtype2_get_glyph_index(gs_font_type42 *pfont, gs_glyph glyph) |
84 | 1.48M | { |
85 | 1.48M | pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)pfont->client_data; |
86 | 1.48M | uint gid = glyph - GS_MIN_CID_GLYPH; |
87 | 1.48M | int code = 0; |
88 | | |
89 | 1.48M | if (glyph < GS_MIN_CID_GLYPH) { |
90 | 0 | gid = 0; |
91 | 0 | } |
92 | 1.48M | else { |
93 | 1.48M | if (glyph < GS_MIN_GLYPH_INDEX) { |
94 | 1.47M | if (pdffont11->substitute == true) { |
95 | 746k | unsigned int ucc = 0; |
96 | 746k | code = pfont->procs.decode_glyph((gs_font *)pfont, glyph, -1, NULL, 0); |
97 | 746k | if (code == 2) { |
98 | 6.26k | uchar sccode[2] = {0}; |
99 | 6.26k | (void)pfont->procs.decode_glyph((gs_font *)pfont, glyph, -1, (ushort *)&sccode, 2); |
100 | 6.26k | ucc = (sccode[0] << 8) + sccode[1]; |
101 | 6.26k | } |
102 | 739k | else if (code == 4) { |
103 | 0 | uchar iccode[4] = {0}; |
104 | 0 | (void)pfont->procs.decode_glyph((gs_font *)pfont, glyph, -1, (ushort *)&iccode, 2); |
105 | 0 | ucc = (iccode[0] << 24) + (iccode[1] << 16) + (iccode[2] << 8) + iccode[3]; |
106 | |
|
107 | 0 | } |
108 | 746k | if (code == 2 || code == 4) { |
109 | 6.26k | code = pdfi_fapi_check_cmap_for_GID((gs_font *)pfont, (unsigned int)ucc, &gid); |
110 | 6.26k | if (code < 0 || gid == 0) |
111 | 8 | gid = glyph - GS_MIN_CID_GLYPH; |
112 | 6.26k | } |
113 | 746k | } |
114 | | |
115 | 1.47M | if (code == 0 && pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > (gid << 1) + 1) { |
116 | 733k | gid = pdffont11->cidtogidmap->data[gid << 1] << 8 | pdffont11->cidtogidmap->data[(gid << 1) + 1]; |
117 | 733k | } |
118 | 1.47M | } |
119 | 1.48M | } |
120 | | |
121 | 1.48M | return gid; |
122 | 1.48M | } |
123 | | |
124 | | static int |
125 | | pdfi_cidtype2_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat, |
126 | | int members, gs_glyph_info_t *info) |
127 | 947k | { |
128 | 947k | int code; |
129 | 947k | pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)font->client_data; |
130 | 947k | int submembers = members & ~(GLYPH_INFO_WIDTHS | GLYPH_INFO_VVECTOR0 | GLYPH_INFO_VVECTOR1 | GLYPH_INFO_CDEVPROC); |
131 | | |
132 | | /* Call with the values we should get below removed from the "members" request */ |
133 | 947k | code = (*pdffont11->orig_glyph_info)(font, glyph, pmat, submembers, info); |
134 | | |
135 | 947k | if (code >= 0 && (members & GLYPH_INFO_WIDTHS) != 0 |
136 | 947k | && glyph > GS_MIN_CID_GLYPH |
137 | 947k | && glyph < GS_MIN_GLYPH_INDEX) { |
138 | 820k | double widths[6] = {0}; |
139 | 820k | code = pdfi_get_cidfont_glyph_metrics(font, (glyph - GS_MIN_CID_GLYPH), widths, true); |
140 | 820k | if (code < 0) { |
141 | | /* If we couldn't get values back from W/W2, give up, and fill everything in from glyph_info */ |
142 | 1.07k | code = (*pdffont11->orig_glyph_info)(font, glyph, pmat, members, info); |
143 | 1.07k | } |
144 | 819k | else { |
145 | 819k | if (pmat == NULL) { |
146 | 557k | info->width[0].x = widths[GLYPH_W0_WIDTH_INDEX] / 1000.0; |
147 | 557k | info->width[0].y = widths[GLYPH_W0_HEIGHT_INDEX] / 1000.0; |
148 | 557k | } |
149 | 262k | else { |
150 | 262k | code = gs_point_transform(widths[GLYPH_W0_WIDTH_INDEX] / 1000.0, widths[GLYPH_W0_HEIGHT_INDEX] / 1000.0, pmat, &info->width[0]); |
151 | 262k | if (code < 0) |
152 | 0 | return code; |
153 | 262k | } |
154 | 819k | info->members |= GLYPH_INFO_WIDTH0; |
155 | | |
156 | 819k | if ((members & GLYPH_INFO_WIDTH1) != 0 |
157 | 819k | && (widths[GLYPH_W1_WIDTH_INDEX] != 0 |
158 | 174 | || widths[GLYPH_W1_HEIGHT_INDEX] != 0)) { |
159 | 174 | if (pmat == NULL) { |
160 | 174 | info->width[1].x = widths[GLYPH_W1_WIDTH_INDEX] / 1000.0; |
161 | 174 | info->width[1].y = widths[GLYPH_W1_HEIGHT_INDEX] / 1000.0; |
162 | 174 | } |
163 | 0 | else { |
164 | 0 | code = gs_point_transform(widths[GLYPH_W1_WIDTH_INDEX] / 1000.0, widths[GLYPH_W1_HEIGHT_INDEX] / 1000.0, pmat, &info->width[1]); |
165 | 0 | if (code < 0) |
166 | 0 | return code; |
167 | 0 | } |
168 | 174 | info->members |= GLYPH_INFO_WIDTH1; |
169 | 174 | } |
170 | 819k | if ((members & GLYPH_INFO_VVECTOR1) != 0) { |
171 | 174 | if (pmat == NULL) { |
172 | 174 | info->v.x = widths[GLYPH_W1_V_X_INDEX] / 1000.0; |
173 | 174 | info->v.y = widths[GLYPH_W1_V_Y_INDEX] / 1000.0; |
174 | 174 | } |
175 | 0 | else { |
176 | 0 | code = gs_point_transform(widths[GLYPH_W1_V_X_INDEX] / 1000.0, widths[GLYPH_W1_V_Y_INDEX] / 1000.0, pmat, &info->v); |
177 | 0 | if (code < 0) |
178 | 0 | return code; |
179 | 0 | } |
180 | 174 | info->members |= GLYPH_INFO_VVECTOR1; |
181 | 174 | } |
182 | 819k | } |
183 | 820k | } |
184 | | |
185 | 947k | return code; |
186 | 947k | } |
187 | | |
188 | | static int |
189 | | pdfi_cidtype2_enumerate_glyph(gs_font *font, int *pindex, |
190 | | gs_glyph_space_t glyph_space, gs_glyph *pglyph) |
191 | 292k | { |
192 | 292k | int code = 0; |
193 | 292k | gs_font_cid2 *cid2 = (gs_font_cid2 *)font; |
194 | 292k | pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)font->client_data; |
195 | 292k | *pglyph = 0; |
196 | | |
197 | 292k | if (*pindex <= 0) |
198 | 4.27k | *pindex = 0; |
199 | | |
200 | 292k | if (pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > 0) { |
201 | 34.5M | do { |
202 | 34.5M | *pglyph = pdffont11->cidtogidmap->data[(*pindex) << 1] << 8 | pdffont11->cidtogidmap->data[((*pindex) << 1) + 1]; |
203 | 34.5M | (*pindex)++; |
204 | 34.5M | if (*pglyph == 0 && *pindex == 1) /* notdef - special case */ |
205 | 1.19k | break; |
206 | 34.5M | } while (*pglyph == 0 && ((*pindex) << 1) < pdffont11->cidtogidmap->length); |
207 | | |
208 | 289k | if (((*pindex) << 1) >= pdffont11->cidtogidmap->length) { |
209 | 652 | *pindex = 0; |
210 | 652 | } |
211 | 288k | else { |
212 | 288k | if (*pglyph != 0 || (*pglyph == 0 && *pindex == 1)) { |
213 | 288k | if (glyph_space == GLYPH_SPACE_INDEX) { |
214 | 0 | *pglyph += GS_MIN_GLYPH_INDEX; |
215 | 0 | } |
216 | 288k | else { |
217 | 288k | *pglyph = (*pindex) + GS_MIN_CID_GLYPH; |
218 | 288k | } |
219 | 288k | } |
220 | 288k | } |
221 | 289k | } |
222 | 3.07k | else { |
223 | 3.07k | if (*pindex < cid2->cidata.common.CIDCount) { |
224 | 3.07k | if (glyph_space == GLYPH_SPACE_INDEX) { |
225 | 0 | *pglyph = *pindex + GS_MIN_GLYPH_INDEX; |
226 | 0 | } |
227 | 3.07k | else { |
228 | 3.07k | *pglyph = (*pindex) + GS_MIN_CID_GLYPH; |
229 | 3.07k | } |
230 | 3.07k | } |
231 | 0 | else { |
232 | 0 | *pindex = 0; |
233 | 0 | } |
234 | 3.07k | } |
235 | | |
236 | 0 | return code; |
237 | 292k | } |
238 | | |
239 | | static void pdfi_set_cidtype2_custom_procs(pdf_cidfont_type2 *pdfttfont) |
240 | 13.9k | { |
241 | 13.9k | gs_font_type42 *pfont = (gs_font_type42 *)pdfttfont->pfont; |
242 | 13.9k | pdfttfont->default_font_info = pfont->procs.font_info; |
243 | 13.9k | pfont->procs.font_info = pdfi_default_font_info; |
244 | 13.9k | } |
245 | | |
246 | | static int |
247 | | pdfi_alloc_cidtype2_font(pdf_context *ctx, pdf_cidfont_type2 **font, bool is_cid) |
248 | 16.0k | { |
249 | 16.0k | pdf_cidfont_type2 *ttfont = NULL; |
250 | 16.0k | gs_font_cid2 *pfont = NULL; |
251 | | |
252 | 16.0k | ttfont = (pdf_cidfont_type2 *)gs_alloc_bytes(ctx->memory, sizeof(pdf_cidfont_type2), "pdfi (cidtype2 pdf_font)"); |
253 | 16.0k | if (ttfont == NULL) |
254 | 0 | return_error(gs_error_VMerror); |
255 | | |
256 | 16.0k | memset(ttfont, 0x00, sizeof(pdf_cidfont_type2)); |
257 | 16.0k | ttfont->type = PDF_FONT; |
258 | 16.0k | ttfont->ctx = ctx; |
259 | 16.0k | ttfont->pdfi_font_type = e_pdf_cidfont_type2; |
260 | | |
261 | | #if REFCNT_DEBUG |
262 | | ttfont->UID = ctx->UID++; |
263 | | outprintf(ctx->memory, "Allocated object of type %c with UID %"PRIi64"\n", ttfont->type, ttfont->UID); |
264 | | #endif |
265 | | |
266 | 16.0k | pdfi_countup(ttfont); |
267 | | |
268 | 16.0k | pfont = (gs_font_cid2 *)gs_alloc_struct(ctx->memory, gs_font_cid2, &st_gs_font_cid2, |
269 | 16.0k | "pdfi (cidtype2 pfont)"); |
270 | 16.0k | if (pfont == NULL) { |
271 | 0 | pdfi_countdown(ttfont); |
272 | 0 | return_error(gs_error_VMerror); |
273 | 0 | } |
274 | 16.0k | memset(pfont, 0x00, sizeof(gs_font_cid2)); |
275 | | |
276 | 16.0k | ttfont->pfont = (gs_font_base *)pfont; |
277 | | |
278 | 16.0k | gs_make_identity(&pfont->orig_FontMatrix); |
279 | 16.0k | gs_make_identity(&pfont->FontMatrix); |
280 | 16.0k | pfont->next = pfont->prev = 0; |
281 | 16.0k | pfont->memory = ctx->memory; |
282 | 16.0k | pfont->dir = ctx->font_dir; |
283 | 16.0k | pfont->is_resource = false; |
284 | 16.0k | gs_notify_init(&pfont->notify_list, ctx->memory); |
285 | 16.0k | pfont->base = (gs_font *) ttfont->pfont; |
286 | 16.0k | pfont->client_data = ttfont; |
287 | 16.0k | pfont->WMode = 0; |
288 | 16.0k | pfont->PaintType = 0; |
289 | 16.0k | pfont->StrokeWidth = 0; |
290 | 16.0k | pfont->is_cached = 0; |
291 | 16.0k | pfont->FAPI = NULL; |
292 | 16.0k | pfont->FAPI_font_data = NULL; |
293 | 16.0k | pfont->procs.init_fstack = gs_default_init_fstack; |
294 | 16.0k | pfont->procs.next_char_glyph = gs_default_next_char_glyph; |
295 | 16.0k | pfont->FontType = ft_CID_TrueType; |
296 | 16.0k | pfont->ExactSize = fbit_use_outlines; |
297 | 16.0k | pfont->InBetweenSize = fbit_use_outlines; |
298 | 16.0k | pfont->TransformedChar = fbit_use_outlines; |
299 | | /* We may want to do something clever with an XUID here */ |
300 | 16.0k | pfont->id = gs_next_ids(ctx->memory, 1); |
301 | 16.0k | uid_set_UniqueID(&pfont->UID, pfont->id); |
302 | | /* The buildchar proc will be filled in by FAPI - |
303 | | we won't worry about working without FAPI */ |
304 | 16.0k | pfont->procs.encode_char = pdfi_encode_char; |
305 | 16.0k | pfont->data.string_proc = pdfi_cidtype2_string_proc; |
306 | 16.0k | pfont->procs.glyph_name = ctx->get_glyph_name; |
307 | 16.0k | pfont->procs.decode_glyph = pdfi_cidfont_decode_glyph; |
308 | 16.0k | pfont->procs.define_font = gs_no_define_font; |
309 | 16.0k | pfont->procs.make_font = gs_no_make_font; |
310 | | |
311 | 16.0k | ttfont->default_font_info = gs_default_font_info; |
312 | 16.0k | pfont->procs.font_info = pdfi_default_font_info; |
313 | | |
314 | 16.0k | pfont->procs.glyph_info = gs_default_glyph_info; |
315 | 16.0k | pfont->procs.glyph_outline = gs_no_glyph_outline; |
316 | 16.0k | pfont->procs.build_char = NULL; |
317 | 16.0k | pfont->procs.same_font = gs_default_same_font; |
318 | 16.0k | pfont->procs.enumerate_glyph = gs_no_enumerate_glyph; |
319 | | |
320 | 16.0k | pfont->encoding_index = ENCODING_INDEX_UNKNOWN; |
321 | 16.0k | pfont->nearest_encoding_index = ENCODING_INDEX_UNKNOWN; |
322 | | |
323 | 16.0k | cid_system_info_set_null(&pfont->cidata.common.CIDSystemInfo); |
324 | 16.0k | pfont->cidata.common.CIDCount = 0; /* set later */ |
325 | 16.0k | pfont->cidata.common.GDBytes = 2; /* not used */ |
326 | 16.0k | pfont->cidata.MetricsCount = 0; |
327 | 16.0k | pfont->cidata.CIDMap_proc = pdfi_cidtype2_CIDMap_proc; |
328 | | |
329 | 16.0k | pfont->client_data = (void *)ttfont; |
330 | | |
331 | 16.0k | *font = ttfont; |
332 | 16.0k | return 0; |
333 | 16.0k | } |
334 | | |
335 | | int pdfi_read_cidtype2_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, pdf_dict *page_dict, byte *buf, int64_t buflen, int findex, pdf_font **ppfont) |
336 | 23.5k | { |
337 | 23.5k | pdf_cidfont_type2 *font; |
338 | 23.5k | int code = 0; |
339 | 23.5k | pdf_obj *fontdesc = NULL; |
340 | 23.5k | pdf_obj *obj = NULL; |
341 | 23.5k | gs_font_cid2 *cid2; |
342 | | |
343 | 23.5k | if (ppfont == NULL) |
344 | 0 | return_error(gs_error_invalidaccess); |
345 | | |
346 | 23.5k | *ppfont = NULL; |
347 | | |
348 | 23.5k | code = pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc); |
349 | 23.5k | if (code <= 0) { |
350 | | /* We own the buffer now, so we must free it on error */ |
351 | 7.52k | gs_free_object(ctx->memory, buf, "pdfi_read_cidtype2_font"); |
352 | 7.52k | return_error(gs_error_invalidfont); |
353 | 7.52k | } |
354 | | |
355 | 16.0k | if ((code = pdfi_alloc_cidtype2_font(ctx, &font, false)) < 0) { |
356 | | /* We own the buffer now, so we must free it on error */ |
357 | 0 | gs_free_object(ctx->memory, buf, "pdfi_read_cidtype2_font"); |
358 | 0 | pdfi_countdown(fontdesc); |
359 | 0 | return code; |
360 | 0 | } |
361 | 16.0k | font->PDF_font = font_dict; |
362 | 16.0k | pdfi_countup(font_dict); |
363 | 16.0k | font->object_num = font_dict->object_num; |
364 | 16.0k | font->generation_num = font_dict->generation_num; |
365 | 16.0k | font->indirect_num = font_dict->indirect_num; |
366 | 16.0k | font->indirect_gen = font_dict->indirect_gen; |
367 | | |
368 | 16.0k | font->FontDescriptor = (pdf_dict *)fontdesc; |
369 | 16.0k | fontdesc = NULL; |
370 | | |
371 | 16.0k | code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&font->sfnt); |
372 | 16.0k | if (code < 0) { |
373 | 0 | goto error; |
374 | 0 | } |
375 | 16.0k | pdfi_countup(font->sfnt); |
376 | 16.0k | code = pdfi_buffer_set_data((pdf_obj *)font->sfnt, buf, buflen); |
377 | 16.0k | if (code < 0) { |
378 | 0 | goto error; |
379 | 0 | } |
380 | 16.0k | buf = NULL; |
381 | | |
382 | | /* Strictly speaking BaseFont is required, but we can continue without one */ |
383 | 16.0k | code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, (pdf_obj **)&obj); |
384 | 16.0k | if (code > 0) { |
385 | 15.8k | pdf_name *nobj = (pdf_name *)obj; |
386 | 15.8k | int nlen = nobj->length > gs_font_name_max ? gs_font_name_max : nobj->length; |
387 | | |
388 | 15.8k | memcpy(font->pfont->key_name.chars, nobj->data, nlen); |
389 | 15.8k | font->pfont->key_name.chars[nlen] = 0; |
390 | 15.8k | font->pfont->key_name.size = nlen; |
391 | 15.8k | memcpy(font->pfont->font_name.chars, nobj->data, nlen); |
392 | 15.8k | font->pfont->font_name.chars[nlen] = 0; |
393 | 15.8k | font->pfont->font_name.size = nlen; |
394 | 15.8k | pdfi_countdown(obj); |
395 | 15.8k | obj = NULL; |
396 | 15.8k | } |
397 | | |
398 | 16.0k | code = pdfi_dict_knownget_number(ctx, font_dict, "DW", &font->DW); |
399 | 16.0k | if (code <= 0) { |
400 | 3.13k | font->DW = 1000; |
401 | 3.13k | } |
402 | | |
403 | 16.0k | code = pdfi_dict_knownget_type(ctx, font_dict, "DW2", PDF_ARRAY, (pdf_obj **)&obj); |
404 | 16.0k | if (code > 0) { |
405 | 107 | font->DW2 = (pdf_array *)obj; |
406 | 107 | obj = NULL; |
407 | 107 | } |
408 | 15.9k | else { |
409 | 15.9k | font->DW2 = NULL; |
410 | 15.9k | } |
411 | 16.0k | code = pdfi_dict_knownget_type(ctx, font_dict, "W", PDF_ARRAY, (pdf_obj **)&obj); |
412 | 16.0k | if (code > 0) { |
413 | 13.2k | font->W = (pdf_array *)obj; |
414 | 13.2k | obj = NULL; |
415 | 13.2k | } |
416 | 2.79k | else { |
417 | 2.79k | font->W = NULL; |
418 | 2.79k | } |
419 | 16.0k | code = pdfi_dict_knownget_type(ctx, font_dict, "W2", PDF_ARRAY, (pdf_obj **)&obj); |
420 | 16.0k | if (code > 0) { |
421 | 0 | font->W2 = (pdf_array *)obj; |
422 | 0 | obj = NULL; |
423 | 0 | } |
424 | 16.0k | else { |
425 | 16.0k | font->W2 = NULL; |
426 | 16.0k | } |
427 | | |
428 | 16.0k | code = pdfi_dict_knownget(ctx, font_dict, "CIDToGIDMap", (pdf_obj **)&obj); |
429 | 16.0k | if (code > 0) { |
430 | | /* CIDToGIDMap can only be a stream or a name, and if it's a name |
431 | | it's only permitted to be "/Identity", so ignore it |
432 | | */ |
433 | 10.6k | if (pdfi_type_of(obj) == PDF_STREAM) { |
434 | 1.93k | byte *d; |
435 | 1.93k | int64_t sz = 0; |
436 | | |
437 | 1.93k | code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&font->cidtogidmap); |
438 | 1.93k | if (code < 0) { |
439 | 0 | goto error; |
440 | 0 | } |
441 | 1.93k | pdfi_countup(font->cidtogidmap); |
442 | 1.93k | code = pdfi_stream_to_buffer(ctx, (pdf_stream *)obj, &d, &sz); |
443 | 1.93k | if (code < 0) { |
444 | 12 | goto error; |
445 | 12 | } |
446 | 1.92k | code = pdfi_buffer_set_data((pdf_obj *)font->cidtogidmap, d, (int32_t)sz); |
447 | 1.92k | if (code < 0) { |
448 | 0 | goto error; |
449 | 0 | } |
450 | 1.92k | } |
451 | 10.6k | pdfi_countdown(obj); |
452 | 10.6k | obj = NULL; |
453 | 10.6k | } |
454 | | |
455 | 16.0k | cid2 = (gs_font_cid2 *)font->pfont; |
456 | | |
457 | 16.0k | code = pdfi_dict_knownget_type(ctx, font_dict, "CIDSystemInfo", PDF_DICT, (pdf_obj **)&obj); |
458 | 16.0k | if (code <= 0) { |
459 | 1.39k | cid2->cidata.common.CIDSystemInfo.Registry.data = NULL; |
460 | 1.39k | cid2->cidata.common.CIDSystemInfo.Registry.size = 0; |
461 | 1.39k | cid2->cidata.common.CIDSystemInfo.Ordering.data = NULL; |
462 | 1.39k | cid2->cidata.common.CIDSystemInfo.Ordering.size = 0; |
463 | 1.39k | } |
464 | 14.6k | else { |
465 | 14.6k | pdf_num *suppl = NULL; |
466 | | |
467 | 14.6k | code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Registry", PDF_STRING, (pdf_obj **)&font->registry); |
468 | 14.6k | if (code <= 0) { |
469 | 23 | cid2->cidata.common.CIDSystemInfo.Registry.data = NULL; |
470 | 23 | cid2->cidata.common.CIDSystemInfo.Registry.size = 0; |
471 | 23 | } |
472 | 14.6k | else { |
473 | 14.6k | cid2->cidata.common.CIDSystemInfo.Registry.data = font->registry->data; |
474 | 14.6k | cid2->cidata.common.CIDSystemInfo.Registry.size = font->registry->length; |
475 | 14.6k | } |
476 | 14.6k | code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Ordering", PDF_STRING, (pdf_obj **)&font->ordering); |
477 | 14.6k | if (code <= 0) { |
478 | 24 | cid2->cidata.common.CIDSystemInfo.Ordering.data = NULL; |
479 | 24 | cid2->cidata.common.CIDSystemInfo.Ordering.size = 0; |
480 | 24 | } |
481 | 14.6k | else { |
482 | 14.6k | cid2->cidata.common.CIDSystemInfo.Ordering.data = font->ordering->data; |
483 | 14.6k | cid2->cidata.common.CIDSystemInfo.Ordering.size = font->ordering->length; |
484 | 14.6k | } |
485 | 14.6k | code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Supplement", PDF_INT, (pdf_obj **)&suppl); |
486 | 14.6k | if (code <= 0) { |
487 | 98 | cid2->cidata.common.CIDSystemInfo.Supplement = font->supplement = 0; |
488 | 98 | } |
489 | 14.5k | else { |
490 | 14.5k | cid2->cidata.common.CIDSystemInfo.Supplement = font->supplement = suppl->value.i; |
491 | 14.5k | } |
492 | 14.6k | pdfi_countdown(suppl); |
493 | 14.6k | } |
494 | 16.0k | pdfi_countdown(obj); |
495 | 16.0k | obj = NULL; |
496 | | |
497 | | |
498 | 16.0k | code = gs_type42_font_init((gs_font_type42 *)font->pfont, findex); |
499 | 16.0k | if (code < 0) { |
500 | 2.12k | goto error; |
501 | 2.12k | } |
502 | 13.9k | pdfi_set_cidtype2_custom_procs(font); |
503 | | |
504 | 13.9k | if (uid_is_XUID(&font->pfont->UID)) |
505 | 13.9k | uid_free(&font->pfont->UID, font->pfont->memory, "pdfi_read_type1_font"); |
506 | 13.9k | uid_set_invalid(&font->pfont->UID); |
507 | 13.9k | font->pfont->id = gs_next_ids(ctx->memory, 1); |
508 | | |
509 | 13.9k | code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, font->pfont); |
510 | 13.9k | if (code < 0) |
511 | 0 | goto error; |
512 | | |
513 | | |
514 | 13.9k | font->orig_glyph_info = font->pfont->procs.glyph_info; |
515 | 13.9k | font->pfont->procs.glyph_info = pdfi_cidtype2_glyph_info; |
516 | 13.9k | font->pfont->procs.enumerate_glyph = pdfi_cidtype2_enumerate_glyph; |
517 | | |
518 | 13.9k | if (font->cidtogidmap != NULL) { |
519 | 1.71k | gs_font_cid2 *cid2 = (gs_font_cid2 *)font->pfont; |
520 | 1.71k | if (cid2->data.numGlyphs > font->cidtogidmap->length >> 1) |
521 | 462 | cid2->cidata.common.CIDCount = cid2->data.numGlyphs; |
522 | 1.24k | else { |
523 | 1.24k | cid2->cidata.common.CIDCount = font->cidtogidmap->length >> 1; |
524 | 1.24k | } |
525 | 1.71k | cid2->cidata.common.MaxCID = cid2->cidata.common.CIDCount; |
526 | 1.71k | } |
527 | 12.2k | else { |
528 | 12.2k | gs_font_cid2 *cid2 = (gs_font_cid2 *)font->pfont; |
529 | 12.2k | cid2->cidata.common.CIDCount = cid2->data.numGlyphs; |
530 | 12.2k | cid2->cidata.common.MaxCID = cid2->cidata.common.CIDCount; |
531 | 12.2k | } |
532 | 13.9k | cid2->data.substitute_glyph_index_vertical = gs_type42_substitute_glyph_index_vertical; |
533 | 13.9k | cid2->cidata.orig_procs.get_outline = cid2->data.get_outline; |
534 | 13.9k | cid2->data.get_glyph_index = pdfi_cidtype2_get_glyph_index; |
535 | | |
536 | 13.9k | pdfi_font_set_orig_fonttype(ctx, (pdf_font *)font); |
537 | 13.9k | code = gs_definefont(ctx->font_dir, (gs_font *)font->pfont); |
538 | 13.9k | if (code < 0) { |
539 | 0 | goto error; |
540 | 0 | } |
541 | | |
542 | 13.9k | code = pdfi_fapi_passfont((pdf_font *)font, findex, NULL, NULL, font->sfnt->data, font->sfnt->length); |
543 | 13.9k | if (code < 0) { |
544 | 432 | goto error; |
545 | 432 | } |
546 | | |
547 | | /* object_num can be zero if the dictionary was defined inline */ |
548 | 13.4k | if (font->object_num != 0) { |
549 | 12.7k | (void)replace_cache_entry(ctx, (pdf_obj *)font); |
550 | 12.7k | } |
551 | | |
552 | 13.4k | *ppfont = (pdf_font *)font; |
553 | 13.4k | return code; |
554 | 2.56k | error: |
555 | 2.56k | pdfi_countdown(obj); |
556 | 2.56k | obj = NULL; |
557 | 2.56k | if (pdfi_dict_get(ctx, font_dict, ".Path", &obj) >= 0) |
558 | 0 | { |
559 | 0 | char fname[gp_file_name_sizeof + 1]; |
560 | 0 | pdf_string *fobj = (pdf_string *)obj; |
561 | |
|
562 | 0 | memcpy(fname, fobj->data, fobj->length > gp_file_name_sizeof ? gp_file_name_sizeof : fobj->length); |
563 | 0 | fname[fobj->length > gp_file_name_sizeof ? gp_file_name_sizeof : fobj->length] = '\0'; |
564 | |
|
565 | 0 | (void)pdfi_set_error_var(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_read_cidtype2_font", "Error reading CIDType2/TrueType font file %s\n", fname); |
566 | 0 | } |
567 | 2.56k | else { |
568 | 2.56k | (void)pdfi_set_error_var(ctx, code, NULL, E_PDF_BADSTREAM, "pdfi_read_cidtype2_font", "Error reading embedded CIDType2/TrueType font object %u\n", font_dict->object_num); |
569 | 2.56k | } |
570 | | |
571 | 2.56k | pdfi_countdown(obj); |
572 | 2.56k | pdfi_countdown(font); |
573 | 2.56k | return code; |
574 | 13.9k | } |
575 | | |
576 | | int pdfi_free_font_cidtype2(pdf_obj *font) |
577 | 16.0k | { |
578 | 16.0k | pdf_cidfont_type2 *pdfcidf = (pdf_cidfont_type2 *)font; |
579 | 16.0k | gs_font_cid2 *pfont = (gs_font_cid2 *)pdfcidf->pfont; |
580 | 16.0k | gs_free_object(OBJ_MEMORY(pdfcidf), pfont, "pdfi_free_font_cidtype2(pfont)"); |
581 | | |
582 | 16.0k | pdfi_countdown(pdfcidf->cidtogidmap); |
583 | | |
584 | 16.0k | pdfi_countdown(pdfcidf->sfnt); |
585 | 16.0k | pdfi_countdown(pdfcidf->PDF_font); |
586 | 16.0k | pdfi_countdown(pdfcidf->BaseFont); |
587 | 16.0k | pdfi_countdown(pdfcidf->FontDescriptor); |
588 | 16.0k | pdfi_countdown(pdfcidf->W); |
589 | 16.0k | pdfi_countdown(pdfcidf->DW2); |
590 | 16.0k | pdfi_countdown(pdfcidf->W2); |
591 | 16.0k | pdfi_countdown(pdfcidf->registry); |
592 | 16.0k | pdfi_countdown(pdfcidf->ordering); |
593 | 16.0k | pdfi_countdown(pdfcidf->filename); |
594 | 16.0k | pdfi_countdown(pdfcidf->copyright); |
595 | 16.0k | pdfi_countdown(pdfcidf->notice); |
596 | 16.0k | pdfi_countdown(pdfcidf->fullname); |
597 | 16.0k | pdfi_countdown(pdfcidf->familyname); |
598 | | |
599 | 16.0k | gs_free_object(OBJ_MEMORY(pdfcidf), pdfcidf, "pdfi_free_font_cidtype2(pdfcidf)"); |
600 | 16.0k | return 0; |
601 | | |
602 | 0 | return 0; |
603 | 16.0k | } |