/src/ghostpdl/pdf/pdf_font11.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2020-2022 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, |
13 | | CA 94945, U.S.A., +1(415)492-9861, for further information. |
14 | | */ |
15 | | |
16 | | /* code for 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 | 93.8M | { |
36 | 93.8M | pdf_cidfont_type2 *ttfont = (pdf_cidfont_type2 *)pfont->client_data; |
37 | 93.8M | int code = 0; |
38 | | |
39 | 93.8M | if (offset + length > ttfont->sfnt->length) { |
40 | 730k | *pdata = NULL; |
41 | 730k | code = gs_note_error(gs_error_invalidfont); |
42 | 730k | } |
43 | 93.0M | else { |
44 | 93.0M | *pdata = ttfont->sfnt->data + offset; |
45 | 93.0M | } |
46 | 93.8M | return code; |
47 | 93.8M | } |
48 | | |
49 | | static int pdfi_cidtype2_CIDMap_proc(gs_font_cid2 *pfont, gs_glyph glyph) |
50 | 74.8k | { |
51 | 74.8k | pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)pfont->client_data; |
52 | 74.8k | uint gid = glyph - GS_MIN_CID_GLYPH; |
53 | | |
54 | 74.8k | if (pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > (gid << 1) + 1) { |
55 | 25.7k | gid = pdffont11->cidtogidmap->data[gid << 1] << 8 | pdffont11->cidtogidmap->data[(gid << 1) + 1]; |
56 | 25.7k | } |
57 | | |
58 | 74.8k | return (int)gid; |
59 | 74.8k | } |
60 | | |
61 | | static uint pdfi_cidtype2_get_glyph_index(gs_font_type42 *pfont, gs_glyph glyph) |
62 | 238k | { |
63 | 238k | pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)pfont->client_data; |
64 | 238k | uint gid = 0; |
65 | | |
66 | 238k | if (glyph < GS_MIN_CID_GLYPH) { |
67 | 0 | gid = 0; |
68 | 0 | } |
69 | 238k | else { |
70 | 238k | if (glyph < GS_MIN_GLYPH_INDEX) { |
71 | 237k | gid = glyph - GS_MIN_CID_GLYPH; |
72 | 237k | if (pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > (gid << 1) + 1) { |
73 | 83.5k | gid = pdffont11->cidtogidmap->data[gid << 1] << 8 | pdffont11->cidtogidmap->data[(gid << 1) + 1]; |
74 | 83.5k | } |
75 | 237k | } |
76 | 238k | } |
77 | | |
78 | 238k | return gid; |
79 | 238k | } |
80 | | |
81 | | static int |
82 | | pdfi_cidtype2_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat, |
83 | | int members, gs_glyph_info_t *info) |
84 | 141k | { |
85 | 141k | int code; |
86 | 141k | pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)font->client_data; |
87 | 141k | code = (*pdffont11->orig_glyph_info)(font, glyph, pmat, members, info); |
88 | 141k | if (code < 0) |
89 | 767 | return code; |
90 | | |
91 | 140k | if ((members & GLYPH_INFO_WIDTHS) != 0 |
92 | 140k | && glyph > GS_MIN_CID_GLYPH |
93 | 140k | && glyph < GS_MIN_GLYPH_INDEX) { |
94 | 131k | double widths[6] = {0}; |
95 | 131k | code = pdfi_get_cidfont_glyph_metrics(font, (glyph - GS_MIN_CID_GLYPH), widths, true); |
96 | 131k | if (code >= 0) { |
97 | 130k | if (pmat == NULL) { |
98 | 59.3k | info->width[0].x = widths[GLYPH_W0_WIDTH_INDEX] / 1000.0; |
99 | 59.3k | info->width[0].y = widths[GLYPH_W0_HEIGHT_INDEX] / 1000.0; |
100 | 59.3k | } |
101 | 71.6k | else { |
102 | 71.6k | code = gs_point_transform(widths[GLYPH_W0_WIDTH_INDEX] / 1000.0, widths[GLYPH_W0_HEIGHT_INDEX] / 1000.0, pmat, &info->width[0]); |
103 | 71.6k | if (code < 0) |
104 | 0 | return code; |
105 | 71.6k | } |
106 | 130k | info->members |= GLYPH_INFO_WIDTH0; |
107 | | |
108 | 130k | if ((members & GLYPH_INFO_WIDTH1) != 0 |
109 | 130k | && (widths[GLYPH_W1_WIDTH_INDEX] != 0 |
110 | 64 | || widths[GLYPH_W1_HEIGHT_INDEX] != 0)) { |
111 | 64 | if (pmat == NULL) { |
112 | 64 | info->width[1].x = widths[GLYPH_W1_WIDTH_INDEX] / 1000.0; |
113 | 64 | info->width[1].y = widths[GLYPH_W1_HEIGHT_INDEX] / 1000.0; |
114 | 64 | } |
115 | 0 | else { |
116 | 0 | code = gs_point_transform(widths[GLYPH_W1_WIDTH_INDEX] / 1000.0, widths[GLYPH_W1_HEIGHT_INDEX] / 1000.0, pmat, &info->width[1]); |
117 | 0 | if (code < 0) |
118 | 0 | return code; |
119 | 0 | } |
120 | 64 | info->members |= GLYPH_INFO_WIDTH1; |
121 | 64 | } |
122 | 130k | if ((members & GLYPH_INFO_VVECTOR1) != 0) { |
123 | 64 | if (pmat == NULL) { |
124 | 64 | info->v.x = widths[GLYPH_W1_V_X_INDEX] / 1000.0; |
125 | 64 | info->v.y = widths[GLYPH_W1_V_Y_INDEX] / 1000.0; |
126 | 64 | } |
127 | 0 | else { |
128 | 0 | code = gs_point_transform(widths[GLYPH_W1_V_X_INDEX] / 1000.0, widths[GLYPH_W1_V_Y_INDEX] / 1000.0, pmat, &info->v); |
129 | 0 | if (code < 0) |
130 | 0 | return code; |
131 | 0 | } |
132 | 64 | info->members |= GLYPH_INFO_VVECTOR1; |
133 | 64 | } |
134 | 130k | } |
135 | 131k | } |
136 | 140k | return code; |
137 | 140k | } |
138 | | |
139 | | static int |
140 | | pdfi_cidtype2_enumerate_glyph(gs_font *font, int *pindex, |
141 | | gs_glyph_space_t glyph_space, gs_glyph *pglyph) |
142 | 55.6k | { |
143 | 55.6k | int code = 0; |
144 | 55.6k | gs_font_cid2 *cid2 = (gs_font_cid2 *)font; |
145 | 55.6k | pdf_cidfont_type2 *pdffont11 = (pdf_cidfont_type2 *)font->client_data; |
146 | 55.6k | *pglyph = 0; |
147 | | |
148 | 55.6k | if (*pindex <= 0) |
149 | 774 | *pindex = 0; |
150 | | |
151 | 55.6k | if (pdffont11->cidtogidmap != NULL && pdffont11->cidtogidmap->length > 0) { |
152 | 14.9M | do { |
153 | 14.9M | *pglyph = pdffont11->cidtogidmap->data[(*pindex) << 1] << 8 | pdffont11->cidtogidmap->data[((*pindex) << 1) + 1]; |
154 | 14.9M | (*pindex)++; |
155 | 14.9M | if (*pglyph == 0 && *pindex == 1) /* notdef - special case */ |
156 | 500 | break; |
157 | 14.9M | } while (*pglyph == 0 && ((*pindex) << 1) < pdffont11->cidtogidmap->length); |
158 | | |
159 | 55.3k | if (((*pindex) << 1) >= pdffont11->cidtogidmap->length) { |
160 | 278 | *pindex = 0; |
161 | 278 | } |
162 | 55.1k | else { |
163 | 55.1k | if (*pglyph != 0 || (*pglyph == 0 && *pindex == 1)) { |
164 | 55.1k | if (glyph_space == GLYPH_SPACE_INDEX) { |
165 | 0 | *pglyph += GS_MIN_GLYPH_INDEX; |
166 | 0 | } |
167 | 55.1k | else { |
168 | 55.1k | *pglyph = (*pindex) + GS_MIN_CID_GLYPH; |
169 | 55.1k | } |
170 | 55.1k | } |
171 | 55.1k | } |
172 | 55.3k | } |
173 | 270 | else { |
174 | 270 | if (*pindex < cid2->cidata.common.CIDCount) { |
175 | 270 | if (glyph_space == GLYPH_SPACE_INDEX) { |
176 | 0 | *pglyph = *pindex + GS_MIN_GLYPH_INDEX; |
177 | 0 | } |
178 | 270 | else { |
179 | 270 | *pglyph = (*pindex) + GS_MIN_CID_GLYPH; |
180 | 270 | } |
181 | 270 | } |
182 | 0 | else { |
183 | 0 | *pindex = 0; |
184 | 0 | } |
185 | 270 | } |
186 | | |
187 | 0 | return code; |
188 | 55.6k | } |
189 | | |
190 | | static int |
191 | | pdfi_alloc_cidtype2_font(pdf_context *ctx, pdf_cidfont_type2 **font, bool is_cid) |
192 | 3.43k | { |
193 | 3.43k | pdf_cidfont_type2 *ttfont = NULL; |
194 | 3.43k | gs_font_cid2 *pfont = NULL; |
195 | | |
196 | 3.43k | ttfont = (pdf_cidfont_type2 *)gs_alloc_bytes(ctx->memory, sizeof(pdf_cidfont_type2), "pdfi (cidtype2 pdf_font)"); |
197 | 3.43k | if (ttfont == NULL) |
198 | 0 | return_error(gs_error_VMerror); |
199 | | |
200 | 3.43k | memset(ttfont, 0x00, sizeof(pdf_cidfont_type2)); |
201 | 3.43k | ttfont->type = PDF_FONT; |
202 | 3.43k | ttfont->ctx = ctx; |
203 | 3.43k | ttfont->pdfi_font_type = e_pdf_cidfont_type2; |
204 | | |
205 | | #if REFCNT_DEBUG |
206 | | ttfont->UID = ctx->UID++; |
207 | | dmprintf2(ctx->memory, "Allocated object of type %c with UID %"PRIi64"\n", ttfont->type, ttfont->UID); |
208 | | #endif |
209 | | |
210 | 3.43k | pdfi_countup(ttfont); |
211 | | |
212 | 3.43k | pfont = (gs_font_cid2 *)gs_alloc_struct(ctx->memory, gs_font_cid2, &st_gs_font_cid2, |
213 | 3.43k | "pdfi (cidtype2 pfont)"); |
214 | 3.43k | if (pfont == NULL) { |
215 | 0 | pdfi_countdown(ttfont); |
216 | 0 | return_error(gs_error_VMerror); |
217 | 0 | } |
218 | 3.43k | memset(pfont, 0x00, sizeof(gs_font_cid2)); |
219 | | |
220 | 3.43k | ttfont->pfont = (gs_font_base *)pfont; |
221 | | |
222 | 3.43k | gs_make_identity(&pfont->orig_FontMatrix); |
223 | 3.43k | gs_make_identity(&pfont->FontMatrix); |
224 | 3.43k | pfont->next = pfont->prev = 0; |
225 | 3.43k | pfont->memory = ctx->memory; |
226 | 3.43k | pfont->dir = ctx->font_dir; |
227 | 3.43k | pfont->is_resource = false; |
228 | 3.43k | gs_notify_init(&pfont->notify_list, ctx->memory); |
229 | 3.43k | pfont->base = (gs_font *) ttfont->pfont; |
230 | 3.43k | pfont->client_data = ttfont; |
231 | 3.43k | pfont->WMode = 0; |
232 | 3.43k | pfont->PaintType = 0; |
233 | 3.43k | pfont->StrokeWidth = 0; |
234 | 3.43k | pfont->is_cached = 0; |
235 | 3.43k | pfont->FAPI = NULL; |
236 | 3.43k | pfont->FAPI_font_data = NULL; |
237 | 3.43k | pfont->procs.init_fstack = gs_default_init_fstack; |
238 | 3.43k | pfont->procs.next_char_glyph = gs_default_next_char_glyph; |
239 | 3.43k | pfont->FontType = ft_CID_TrueType; |
240 | 3.43k | pfont->ExactSize = fbit_use_outlines; |
241 | 3.43k | pfont->InBetweenSize = fbit_use_outlines; |
242 | 3.43k | pfont->TransformedChar = fbit_use_outlines; |
243 | | /* We may want to do something clever with an XUID here */ |
244 | 3.43k | pfont->id = gs_next_ids(ctx->memory, 1); |
245 | 3.43k | uid_set_UniqueID(&pfont->UID, pfont->id); |
246 | | /* The buildchar proc will be filled in by FAPI - |
247 | | we won't worry about working without FAPI */ |
248 | 3.43k | pfont->procs.encode_char = pdfi_encode_char; |
249 | 3.43k | pfont->data.string_proc = pdfi_cidtype2_string_proc; |
250 | 3.43k | pfont->procs.glyph_name = ctx->get_glyph_name; |
251 | 3.43k | pfont->procs.decode_glyph = pdfi_decode_glyph; |
252 | 3.43k | pfont->procs.define_font = gs_no_define_font; |
253 | 3.43k | pfont->procs.make_font = gs_no_make_font; |
254 | 3.43k | pfont->procs.font_info = gs_default_font_info; |
255 | 3.43k | pfont->procs.glyph_info = gs_default_glyph_info; |
256 | 3.43k | pfont->procs.glyph_outline = gs_no_glyph_outline; |
257 | 3.43k | pfont->procs.build_char = NULL; |
258 | 3.43k | pfont->procs.same_font = gs_default_same_font; |
259 | 3.43k | pfont->procs.enumerate_glyph = gs_no_enumerate_glyph; |
260 | | |
261 | 3.43k | pfont->encoding_index = 1; /****** WRONG ******/ |
262 | 3.43k | pfont->nearest_encoding_index = 1; /****** WRONG ******/ |
263 | | |
264 | 3.43k | cid_system_info_set_null(&pfont->cidata.common.CIDSystemInfo); |
265 | 3.43k | pfont->cidata.common.CIDCount = 0; /* set later */ |
266 | 3.43k | pfont->cidata.common.GDBytes = 2; /* not used */ |
267 | 3.43k | pfont->cidata.MetricsCount = 0; |
268 | 3.43k | pfont->cidata.CIDMap_proc = pdfi_cidtype2_CIDMap_proc; |
269 | | |
270 | 3.43k | pfont->client_data = (void *)ttfont; |
271 | | |
272 | 3.43k | *font = ttfont; |
273 | 3.43k | return 0; |
274 | 3.43k | } |
275 | | |
276 | | 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) |
277 | 4.61k | { |
278 | 4.61k | pdf_cidfont_type2 *font; |
279 | 4.61k | int code = 0; |
280 | 4.61k | pdf_obj *fontdesc = NULL; |
281 | 4.61k | pdf_obj *obj = NULL; |
282 | 4.61k | gs_font_cid2 *cid2; |
283 | | |
284 | 4.61k | if (ppfont == NULL) |
285 | 0 | return_error(gs_error_invalidaccess); |
286 | | |
287 | 4.61k | *ppfont = NULL; |
288 | | |
289 | 4.61k | code = pdfi_dict_knownget_type(ctx, font_dict, "FontDescriptor", PDF_DICT, &fontdesc); |
290 | 4.61k | if (code <= 0) { |
291 | | /* We own the buffer now, so we must free it on error */ |
292 | 1.18k | gs_free_object(ctx->memory, buf, "pdfi_read_cidtype2_font"); |
293 | 1.18k | return_error(gs_error_invalidfont); |
294 | 1.18k | } |
295 | | |
296 | 3.43k | if ((code = pdfi_alloc_cidtype2_font(ctx, &font, false)) < 0) { |
297 | | /* We own the buffer now, so we must free it on error */ |
298 | 0 | gs_free_object(ctx->memory, buf, "pdfi_read_cidtype2_font"); |
299 | 0 | pdfi_countdown(fontdesc); |
300 | 0 | return code; |
301 | 0 | } |
302 | 3.43k | font->PDF_font = font_dict; |
303 | 3.43k | pdfi_countup(font_dict); |
304 | 3.43k | font->object_num = font_dict->object_num; |
305 | 3.43k | font->generation_num = font_dict->generation_num; |
306 | 3.43k | font->indirect_num = font_dict->indirect_num; |
307 | 3.43k | font->indirect_gen = font_dict->indirect_gen; |
308 | | |
309 | 3.43k | font->FontDescriptor = (pdf_dict *)fontdesc; |
310 | 3.43k | fontdesc = NULL; |
311 | | |
312 | 3.43k | code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&font->sfnt); |
313 | 3.43k | if (code < 0) { |
314 | 0 | goto error; |
315 | 0 | } |
316 | 3.43k | pdfi_countup(font->sfnt); |
317 | 3.43k | code = pdfi_buffer_set_data((pdf_obj *)font->sfnt, buf, buflen); |
318 | 3.43k | if (code < 0) { |
319 | 0 | goto error; |
320 | 0 | } |
321 | 3.43k | buf = NULL; |
322 | | |
323 | | /* Strictly speaking BaseFont is required, but we can continue without one */ |
324 | 3.43k | code = pdfi_dict_knownget_type(ctx, font_dict, "BaseFont", PDF_NAME, (pdf_obj **)&obj); |
325 | 3.43k | if (code > 0) { |
326 | 3.42k | pdf_name *nobj = (pdf_name *)obj; |
327 | 3.42k | int nlen = nobj->length > gs_font_name_max ? gs_font_name_max : nobj->length; |
328 | | |
329 | 3.42k | memcpy(font->pfont->key_name.chars, nobj->data, nlen); |
330 | 3.42k | font->pfont->key_name.chars[nlen] = 0; |
331 | 3.42k | font->pfont->key_name.size = nlen; |
332 | 3.42k | memcpy(font->pfont->font_name.chars, nobj->data, nlen); |
333 | 3.42k | font->pfont->font_name.chars[nlen] = 0; |
334 | 3.42k | font->pfont->font_name.size = nlen; |
335 | 3.42k | pdfi_countdown(obj); |
336 | 3.42k | obj = NULL; |
337 | 3.42k | } |
338 | | |
339 | 3.43k | code = pdfi_dict_knownget_type(ctx, font_dict, "DW", PDF_INT, (pdf_obj **)&obj); |
340 | 3.43k | if (code > 0) { |
341 | 2.73k | font->DW = ((pdf_num *)obj)->value.i; |
342 | 2.73k | pdfi_countdown(obj); |
343 | 2.73k | obj = NULL; |
344 | 2.73k | } |
345 | 704 | else { |
346 | 704 | font->DW = 1000; |
347 | 704 | } |
348 | 3.43k | code = pdfi_dict_knownget_type(ctx, font_dict, "DW2", PDF_ARRAY, (pdf_obj **)&obj); |
349 | 3.43k | if (code > 0) { |
350 | 7 | font->DW2 = (pdf_array *)obj; |
351 | 7 | obj = NULL; |
352 | 7 | } |
353 | 3.42k | else { |
354 | 3.42k | font->DW2 = NULL; |
355 | 3.42k | } |
356 | 3.43k | code = pdfi_dict_knownget_type(ctx, font_dict, "W", PDF_ARRAY, (pdf_obj **)&obj); |
357 | 3.43k | if (code > 0) { |
358 | 3.07k | font->W = (pdf_array *)obj; |
359 | 3.07k | obj = NULL; |
360 | 3.07k | } |
361 | 357 | else { |
362 | 357 | font->W = NULL; |
363 | 357 | } |
364 | 3.43k | code = pdfi_dict_knownget_type(ctx, font_dict, "W2", PDF_ARRAY, (pdf_obj **)&obj); |
365 | 3.43k | if (code > 0) { |
366 | 0 | font->W2 = (pdf_array *)obj; |
367 | 0 | obj = NULL; |
368 | 0 | } |
369 | 3.43k | else { |
370 | 3.43k | font->W2 = NULL; |
371 | 3.43k | } |
372 | | |
373 | 3.43k | code = pdfi_dict_knownget(ctx, font_dict, "CIDToGIDMap", (pdf_obj **)&obj); |
374 | 3.43k | if (code > 0) { |
375 | | /* CIDToGIDMap can only be a stream or a name, and if it's a name |
376 | | it's only permitted to be "/Identity", so ignore it |
377 | | */ |
378 | 2.09k | if (pdfi_type_of(obj) == PDF_STREAM) { |
379 | 509 | byte *d; |
380 | 509 | int64_t sz = 0; |
381 | | |
382 | 509 | code = pdfi_object_alloc(ctx, PDF_BUFFER, 0, (pdf_obj **)&font->cidtogidmap); |
383 | 509 | if (code < 0) { |
384 | 0 | goto error; |
385 | 0 | } |
386 | 509 | pdfi_countup(font->cidtogidmap); |
387 | 509 | code = pdfi_stream_to_buffer(ctx, (pdf_stream *)obj, &d, &sz); |
388 | 509 | if (code < 0) { |
389 | 0 | goto error; |
390 | 0 | } |
391 | 509 | code = pdfi_buffer_set_data((pdf_obj *)font->cidtogidmap, d, (int32_t)sz); |
392 | 509 | if (code < 0) { |
393 | 0 | goto error; |
394 | 0 | } |
395 | 509 | } |
396 | 2.09k | pdfi_countdown(obj); |
397 | 2.09k | obj = NULL; |
398 | 2.09k | } |
399 | | |
400 | 3.43k | cid2 = (gs_font_cid2 *)font->pfont; |
401 | | |
402 | 3.43k | code = pdfi_dict_knownget_type(ctx, font_dict, "CIDSystemInfo", PDF_DICT, (pdf_obj **)&obj); |
403 | 3.43k | if (code <= 0) { |
404 | 9 | cid2->cidata.common.CIDSystemInfo.Registry.data = NULL; |
405 | 9 | cid2->cidata.common.CIDSystemInfo.Registry.size = 0; |
406 | 9 | cid2->cidata.common.CIDSystemInfo.Ordering.data = NULL; |
407 | 9 | cid2->cidata.common.CIDSystemInfo.Ordering.size = 0; |
408 | 9 | } |
409 | 3.42k | else { |
410 | 3.42k | pdf_num *suppl = NULL; |
411 | | |
412 | 3.42k | code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Registry", PDF_STRING, (pdf_obj **)&font->registry); |
413 | 3.42k | if (code <= 0) { |
414 | 0 | cid2->cidata.common.CIDSystemInfo.Registry.data = NULL; |
415 | 0 | cid2->cidata.common.CIDSystemInfo.Registry.size = 0; |
416 | 0 | } |
417 | 3.42k | else { |
418 | 3.42k | cid2->cidata.common.CIDSystemInfo.Registry.data = font->registry->data; |
419 | 3.42k | cid2->cidata.common.CIDSystemInfo.Registry.size = font->registry->length; |
420 | 3.42k | } |
421 | 3.42k | code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Ordering", PDF_STRING, (pdf_obj **)&font->ordering); |
422 | 3.42k | if (code <= 0) { |
423 | 1 | cid2->cidata.common.CIDSystemInfo.Ordering.data = NULL; |
424 | 1 | cid2->cidata.common.CIDSystemInfo.Ordering.size = 0; |
425 | 1 | } |
426 | 3.42k | else { |
427 | 3.42k | cid2->cidata.common.CIDSystemInfo.Ordering.data = font->ordering->data; |
428 | 3.42k | cid2->cidata.common.CIDSystemInfo.Ordering.size = font->ordering->length; |
429 | 3.42k | } |
430 | 3.42k | code = pdfi_dict_knownget_type(ctx, (pdf_dict *)obj, "Supplement", PDF_INT, (pdf_obj **)&suppl); |
431 | 3.42k | if (code <= 0) { |
432 | 2 | cid2->cidata.common.CIDSystemInfo.Supplement = font->supplement = 0; |
433 | 2 | } |
434 | 3.42k | else { |
435 | 3.42k | cid2->cidata.common.CIDSystemInfo.Supplement = font->supplement = suppl->value.i; |
436 | 3.42k | } |
437 | 3.42k | pdfi_countdown(suppl); |
438 | 3.42k | } |
439 | 3.43k | pdfi_countdown(obj); |
440 | 3.43k | obj = NULL; |
441 | | |
442 | | |
443 | 3.43k | code = gs_type42_font_init((gs_font_type42 *)font->pfont, 0); |
444 | 3.43k | if (code < 0) { |
445 | 406 | goto error; |
446 | 406 | } |
447 | 3.02k | if (uid_is_XUID(&font->pfont->UID)) |
448 | 3.02k | uid_free(&font->pfont->UID, font->pfont->memory, "pdfi_read_type1_font"); |
449 | 3.02k | uid_set_invalid(&font->pfont->UID); |
450 | 3.02k | font->pfont->id = gs_next_ids(ctx->memory, 1); |
451 | | |
452 | 3.02k | code = pdfi_font_generate_pseudo_XUID(ctx, font_dict, font->pfont); |
453 | 3.02k | if (code < 0) |
454 | 0 | goto error; |
455 | | |
456 | | |
457 | 3.02k | font->orig_glyph_info = font->pfont->procs.glyph_info; |
458 | 3.02k | font->pfont->procs.glyph_info = pdfi_cidtype2_glyph_info; |
459 | 3.02k | font->pfont->procs.enumerate_glyph = pdfi_cidtype2_enumerate_glyph; |
460 | | |
461 | 3.02k | if (font->cidtogidmap != NULL) { |
462 | 460 | gs_font_cid2 *cid2 = (gs_font_cid2 *)font->pfont; |
463 | 460 | if (cid2->data.numGlyphs > font->cidtogidmap->length >> 1) |
464 | 88 | cid2->cidata.common.CIDCount = cid2->data.numGlyphs; |
465 | 372 | else { |
466 | 372 | cid2->cidata.common.CIDCount = font->cidtogidmap->length >> 1; |
467 | 372 | } |
468 | 460 | cid2->cidata.common.MaxCID = cid2->cidata.common.CIDCount; |
469 | 460 | } |
470 | 2.56k | else { |
471 | 2.56k | gs_font_cid2 *cid2 = (gs_font_cid2 *)font->pfont; |
472 | 2.56k | cid2->cidata.common.CIDCount = cid2->data.numGlyphs; |
473 | 2.56k | cid2->cidata.common.MaxCID = cid2->cidata.common.CIDCount; |
474 | 2.56k | } |
475 | 3.02k | cid2->data.substitute_glyph_index_vertical = gs_type42_substitute_glyph_index_vertical; |
476 | 3.02k | cid2->cidata.orig_procs.get_outline = cid2->data.get_outline; |
477 | 3.02k | cid2->data.get_glyph_index = pdfi_cidtype2_get_glyph_index; |
478 | | |
479 | 3.02k | code = gs_definefont(ctx->font_dir, (gs_font *)font->pfont); |
480 | 3.02k | if (code < 0) { |
481 | 0 | goto error; |
482 | 0 | } |
483 | | |
484 | 3.02k | code = pdfi_fapi_passfont((pdf_font *)font, 0, NULL, NULL, font->sfnt->data, font->sfnt->length); |
485 | 3.02k | if (code < 0) { |
486 | 63 | goto error; |
487 | 63 | } |
488 | | |
489 | | /* object_num can be zero if the dictionary was defined inline */ |
490 | 2.96k | if (font->object_num != 0) { |
491 | 2.82k | (void)replace_cache_entry(ctx, (pdf_obj *)font); |
492 | 2.82k | } |
493 | | |
494 | 2.96k | *ppfont = (pdf_font *)font; |
495 | 2.96k | return code; |
496 | 469 | error: |
497 | | |
498 | 469 | pdfi_countdown(obj); |
499 | 469 | pdfi_countdown(font); |
500 | 469 | return code; |
501 | 3.02k | } |
502 | | |
503 | | int pdfi_free_font_cidtype2(pdf_obj *font) |
504 | 3.43k | { |
505 | 3.43k | pdf_cidfont_type2 *pdfcidf = (pdf_cidfont_type2 *)font; |
506 | 3.43k | gs_font_cid2 *pfont = (gs_font_cid2 *)pdfcidf->pfont; |
507 | 3.43k | gs_free_object(OBJ_MEMORY(pdfcidf), pfont, "pdfi_free_font_cidtype2(pfont)"); |
508 | | |
509 | 3.43k | pdfi_countdown(pdfcidf->cidtogidmap); |
510 | | |
511 | 3.43k | pdfi_countdown(pdfcidf->sfnt); |
512 | 3.43k | pdfi_countdown(pdfcidf->PDF_font); |
513 | 3.43k | pdfi_countdown(pdfcidf->BaseFont); |
514 | 3.43k | pdfi_countdown(pdfcidf->FontDescriptor); |
515 | 3.43k | pdfi_countdown(pdfcidf->W); |
516 | 3.43k | pdfi_countdown(pdfcidf->DW2); |
517 | 3.43k | pdfi_countdown(pdfcidf->W2); |
518 | 3.43k | pdfi_countdown(pdfcidf->registry); |
519 | 3.43k | pdfi_countdown(pdfcidf->ordering); |
520 | 3.43k | pdfi_countdown(pdfcidf->filename); |
521 | | |
522 | 3.43k | gs_free_object(OBJ_MEMORY(pdfcidf), pdfcidf, "pdfi_free_font_cidtype2(pdfcidf)"); |
523 | 3.43k | return 0; |
524 | | |
525 | 0 | return 0; |
526 | 3.43k | } |