/src/ghostpdl/pdf/pdf_font0.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2019-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 | | /* Include this first so that we don't get a macro redefnition of 'offsetof' */ |
17 | | #include "pdf_int.h" |
18 | | |
19 | | /* code for type 0 (CID) font handling */ |
20 | | #include "gxfont.h" |
21 | | #include "gxfont0.h" |
22 | | |
23 | | #include "pdf_int.h" |
24 | | #include "pdf_font.h" |
25 | | #include "pdf_font0.h" |
26 | | #include "pdf_font1C.h" |
27 | | #include "pdf_font_types.h" |
28 | | #include "pdf_stack.h" |
29 | | #include "pdf_array.h" |
30 | | #include "pdf_dict.h" |
31 | | #include "pdf_file.h" |
32 | | #include "pdf_cmap.h" |
33 | | #include "pdf_deref.h" |
34 | | |
35 | | #include "gsutil.h" /* For gs_next_ids() */ |
36 | | |
37 | | extern const pdfi_cid_decoding_t *pdfi_cid_decoding_list[]; |
38 | | extern const pdfi_cid_subst_nwp_table_t *pdfi_cid_substnwp_list[]; |
39 | | |
40 | | static void pdfi_font0_cid_subst_tables(const char *reg, const int reglen, const char *ord, |
41 | | const int ordlen, pdfi_cid_decoding_t **decoding, pdfi_cid_subst_nwp_table_t **substnwp) |
42 | 1.54k | { |
43 | 1.54k | int i; |
44 | 1.54k | *decoding = NULL; |
45 | 1.54k | *substnwp = NULL; |
46 | | /* This only makes sense for Adobe orderings */ |
47 | 1.54k | if (reglen == 5 && !memcmp(reg, "Adobe", 5)) { |
48 | 8.21k | for (i = 0; pdfi_cid_decoding_list[i] != NULL; i++) { |
49 | 6.88k | if (strlen(pdfi_cid_decoding_list[i]->s_order) == ordlen && |
50 | 6.88k | !memcmp(pdfi_cid_decoding_list[i]->s_order, ord, ordlen)) { |
51 | 74 | *decoding = (pdfi_cid_decoding_t *)pdfi_cid_decoding_list[i]; |
52 | 74 | break; |
53 | 74 | } |
54 | 6.88k | } |
55 | | /* For now, also only for Adobe orderings */ |
56 | 8.14k | for (i = 0; pdfi_cid_substnwp_list[i] != NULL; i++) { |
57 | 6.81k | if (strlen(pdfi_cid_substnwp_list[i]->ordering) == ordlen && |
58 | 6.81k | !memcmp(pdfi_cid_substnwp_list[i]->ordering, ord, ordlen)) { |
59 | 74 | *substnwp = (pdfi_cid_subst_nwp_table_t *)pdfi_cid_substnwp_list[i]; |
60 | 74 | break; |
61 | 74 | } |
62 | 6.81k | } |
63 | 1.41k | } |
64 | 1.54k | } |
65 | | |
66 | | static int |
67 | | pdfi_font0_glyph_name(gs_font *pfont, gs_glyph index, gs_const_string *pstr) |
68 | 0 | { |
69 | 0 | int code; |
70 | 0 | pdf_font_type0 *pt0font = (pdf_font_type0 *)pfont->client_data; |
71 | 0 | char gnm[64]; |
72 | 0 | pdf_context *ctx = pt0font->ctx; |
73 | 0 | uint gindex = 0; |
74 | |
|
75 | 0 | gs_snprintf(gnm, 64, "%lu", (long)index); |
76 | 0 | code = (*ctx->get_glyph_index)((gs_font *)pfont, (byte *)gnm, strlen(gnm), &gindex); |
77 | 0 | if (code < 0) |
78 | 0 | return code; |
79 | 0 | code = (*ctx->get_glyph_name)(pfont, (gs_glyph)gindex, (gs_const_string *)pstr); |
80 | |
|
81 | 0 | return code; |
82 | 0 | } |
83 | | |
84 | | static int |
85 | | pdfi_font0_map_glyph_to_unicode(gs_font *font, gs_glyph glyph, int ch, ushort *u, unsigned int length) |
86 | 133k | { |
87 | 133k | gs_glyph cc = glyph < GS_MIN_CID_GLYPH ? glyph : glyph - GS_MIN_CID_GLYPH; |
88 | 133k | pdf_font_type0 *pt0font = (pdf_font_type0 *)font->client_data; |
89 | 133k | int code = gs_error_undefined, i; |
90 | 133k | uchar *unicode_return = (uchar *)u; |
91 | 133k | pdf_cidfont_type2 *decfont = NULL; |
92 | 133k | pdfi_cid_subst_nwp_table_t *substnwp = pt0font->substnwp; |
93 | | |
94 | 133k | code = pdfi_array_get(pt0font->ctx, pt0font->DescendantFonts, 0, (pdf_obj **)&decfont); |
95 | 133k | if (code < 0 || pdfi_type_of(decfont) != PDF_FONT) { |
96 | 0 | pdfi_countdown(decfont); |
97 | 0 | return gs_error_undefined; |
98 | 0 | } |
99 | | |
100 | 133k | code = gs_error_undefined; |
101 | 133k | while (1) { /* Loop to make retrying with a substitute CID easier */ |
102 | | /* Favour the ToUnicode if one exists */ |
103 | 133k | code = pdfi_tounicode_char_to_unicode(pt0font->ctx, (pdf_cmap *)pt0font->ToUnicode, glyph, ch, u, length); |
104 | | |
105 | 133k | if (code == gs_error_undefined && pt0font->decoding) { |
106 | 1.53k | const int *n; |
107 | | |
108 | 1.53k | if (cc / 256 < pt0font->decoding->nranges) { |
109 | 1.50k | n = (const int *)pt0font->decoding->ranges[cc / 256][cc % 256]; |
110 | 1.53k | for (i = 0; i < pt0font->decoding->val_sizes; i++) { |
111 | 1.53k | unsigned int cmapcc; |
112 | 1.53k | if (n[i] == -1) |
113 | 195 | break; |
114 | 1.33k | cc = n[i]; |
115 | 1.33k | cmapcc = (unsigned int)cc; |
116 | 1.33k | if (decfont->pdfi_font_type == e_pdf_cidfont_type2) |
117 | 1.33k | code = pdfi_fapi_check_cmap_for_GID((gs_font *)decfont->pfont, (unsigned int)cc, &cmapcc); |
118 | 0 | else |
119 | 0 | code = 0; |
120 | 1.33k | if (code >= 0 && cmapcc != 0){ |
121 | 1.31k | code = 0; |
122 | 1.31k | break; |
123 | 1.31k | } |
124 | 1.33k | } |
125 | | /* If it's a TTF derived CIDFont, we prefer a code point supported by the cmap table |
126 | | but if not, use the first available one |
127 | | */ |
128 | 1.50k | if (code < 0 && n[0] != -1) { |
129 | 0 | cc = n[0]; |
130 | 0 | code = 0; |
131 | 0 | } |
132 | 1.50k | } |
133 | 1.53k | if (code >= 0) { |
134 | 1.31k | if (cc > 65535) { |
135 | 0 | code = 4; |
136 | 0 | if (unicode_return != NULL && length >= code) { |
137 | 0 | unicode_return[0] = (cc & 0xFF000000)>> 24; |
138 | 0 | unicode_return[1] = (cc & 0x00FF0000) >> 16; |
139 | 0 | unicode_return[2] = (cc & 0x0000FF00) >> 8; |
140 | 0 | unicode_return[3] = (cc & 0x000000FF); |
141 | 0 | } |
142 | 0 | } |
143 | 1.31k | else { |
144 | 1.31k | code = 2; |
145 | 1.31k | if (unicode_return != NULL && length >= code) { |
146 | 1.26k | unicode_return[0] = (cc & 0x0000FF00) >> 8; |
147 | 1.26k | unicode_return[1] = (cc & 0x000000FF); |
148 | 1.26k | } |
149 | 1.31k | } |
150 | 1.31k | } |
151 | 1.53k | } |
152 | | /* If we get here, and still don't have a usable code point, check for a |
153 | | pre-defined CID substitution, and if there's one, jump back to the start |
154 | | and try again. |
155 | | */ |
156 | 133k | if (code == gs_error_undefined && substnwp) { |
157 | 1.15k | for (i = 0; substnwp->subst[i].s_type != 0; i++ ) { |
158 | 1.10k | if (cc >= substnwp->subst[i].s_scid && cc <= substnwp->subst[i].e_scid) { |
159 | 0 | cc = substnwp->subst[i].s_dcid + (cc - substnwp->subst[i].s_scid); |
160 | 0 | substnwp = NULL; |
161 | 0 | break; |
162 | 0 | } |
163 | 1.10k | if (cc >= substnwp->subst[i].s_dcid |
164 | 1.10k | && cc <= substnwp->subst[i].s_dcid + (substnwp->subst[i].e_scid - substnwp->subst[i].s_scid)) { |
165 | 174 | cc = substnwp->subst[i].s_scid + (cc - substnwp->subst[i].s_dcid); |
166 | 174 | substnwp = NULL; |
167 | 174 | break; |
168 | 174 | } |
169 | 1.10k | } |
170 | 218 | if (substnwp == NULL) |
171 | 174 | continue; |
172 | 218 | } |
173 | 133k | break; |
174 | 133k | } |
175 | 133k | pdfi_countdown(decfont); |
176 | 133k | return (code < 0 ? 0 : code); |
177 | 133k | } |
178 | | |
179 | | int pdfi_read_type0_font(pdf_context *ctx, pdf_dict *font_dict, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_font **ppdffont) |
180 | 6.85k | { |
181 | 6.85k | int code, nlen; |
182 | 6.85k | pdf_obj *cmap = NULL; |
183 | 6.85k | pdf_cmap *pcmap = NULL; |
184 | 6.85k | pdf_array *arr = NULL; |
185 | 6.85k | pdf_dict *decfontdict = NULL; /* there can only be one */ |
186 | 6.85k | pdf_name *n = NULL; |
187 | 6.85k | pdf_obj *basefont = NULL; |
188 | 6.85k | pdf_obj *tounicode = NULL; |
189 | 6.85k | pdf_dict *dfontdesc = NULL; |
190 | 6.85k | pdf_dict *fontdesc = NULL; |
191 | 6.85k | pdf_stream *ffile = NULL; |
192 | 6.85k | pdf_font *descpfont = NULL; |
193 | 6.85k | pdf_font_type0 *pdft0 = NULL; |
194 | 6.85k | gs_font_type0 *pfont0 = NULL; |
195 | 6.85k | pdfi_cid_decoding_t *dec = NULL; |
196 | 6.85k | pdfi_cid_subst_nwp_table_t *substnwp = NULL; |
197 | | |
198 | | /* We're supposed to have a FontDescriptor, it can be missing, and we have to carry on */ |
199 | 6.85k | (void)pdfi_dict_get(ctx, font_dict, "FontDescriptor", (pdf_obj **)&fontdesc); |
200 | | |
201 | 6.85k | code = pdfi_dict_get(ctx, font_dict, "Encoding", &cmap); |
202 | 6.85k | if (code < 0) goto error; |
203 | | |
204 | 6.80k | if (pdfi_type_of(cmap) == PDF_CMAP) { |
205 | 0 | pcmap = (pdf_cmap *)cmap; |
206 | 0 | cmap = NULL; |
207 | 0 | } |
208 | 6.80k | else { |
209 | 6.80k | code = pdfi_read_cmap(ctx, cmap, &pcmap); |
210 | 6.80k | pdfi_countdown(cmap); |
211 | 6.80k | cmap = NULL; |
212 | 6.80k | if (code < 0) goto error; |
213 | 6.80k | } |
214 | | |
215 | 6.76k | code = pdfi_dict_get(ctx, font_dict, "DescendantFonts", (pdf_obj **)&arr); |
216 | 6.76k | if (code < 0) goto error; |
217 | | |
218 | 6.64k | if (pdfi_type_of(arr) != PDF_ARRAY || arr->size != 1) { |
219 | 3 | code = gs_note_error(gs_error_invalidfont); |
220 | 3 | goto error; |
221 | 3 | } |
222 | 6.64k | code = pdfi_array_get(ctx, arr, 0, (pdf_obj **)&decfontdict); |
223 | 6.64k | pdfi_countdown(arr); |
224 | 6.64k | arr = NULL; |
225 | 6.64k | if (code < 0) goto error; |
226 | 5.71k | switch (pdfi_type_of(decfontdict)) { |
227 | 577 | case PDF_FONT: |
228 | 577 | descpfont = (pdf_font *)decfontdict; |
229 | 577 | decfontdict = descpfont->PDF_font; |
230 | 577 | pdfi_countup(decfontdict); |
231 | 577 | break; |
232 | 4.70k | case PDF_DICT: |
233 | 4.70k | code = pdfi_dict_get(ctx, (pdf_dict *)decfontdict, "Type", (pdf_obj **)&n); |
234 | 4.70k | if (code < 0) goto error; |
235 | 4.68k | if (pdfi_type_of(n) != PDF_NAME || n->length != 4 || memcmp(n->data, "Font", 4) != 0) { |
236 | 8 | pdfi_countdown(n); |
237 | 8 | code = gs_note_error(gs_error_invalidfont); |
238 | 8 | goto error; |
239 | 8 | } |
240 | 4.67k | pdfi_countdown(n); |
241 | 4.67k | break; |
242 | 438 | default: |
243 | 438 | code = gs_note_error(gs_error_invalidfont); |
244 | 438 | goto error; |
245 | 5.71k | } |
246 | | #if 0 |
247 | | code = pdfi_dict_get(ctx, (pdf_dict *)decfontdict, "Subtype", (pdf_obj **)&n); |
248 | | if (code < 0) |
249 | | goto error; |
250 | | |
251 | | if (pdfi_type_of(n) != PDF_NAME || n->length != 12 || memcmp(n->data, "CIDFontType", 11) != 0) { |
252 | | pdfi_countdown(n); |
253 | | code = gs_note_error(gs_error_invalidfont); |
254 | | goto error; |
255 | | } |
256 | | /* cidftype is ignored for now, but we may need to know it when |
257 | | subsitutions are allowed |
258 | | */ |
259 | | cidftype = n->data[11] - 48; |
260 | | |
261 | | pdfi_countdown(n); |
262 | | #endif |
263 | | |
264 | 5.24k | code = pdfi_dict_get(ctx, font_dict, "BaseFont", (pdf_obj **)&basefont); |
265 | 5.24k | if (code < 0) { |
266 | 33 | basefont = NULL; |
267 | 33 | } |
268 | | |
269 | 5.24k | if (ctx->args.ignoretounicode != true) { |
270 | 5.24k | code = pdfi_dict_get(ctx, font_dict, "ToUnicode", (pdf_obj **)&tounicode); |
271 | 5.24k | if (code >= 0 && pdfi_type_of(tounicode) == PDF_STREAM) { |
272 | 3.67k | pdf_cmap *tu = NULL; |
273 | 3.67k | code = pdfi_read_cmap(ctx, tounicode, &tu); |
274 | 3.67k | pdfi_countdown(tounicode); |
275 | 3.67k | tounicode = (pdf_obj *)tu; |
276 | 3.67k | } |
277 | 5.24k | if (code < 0 || (tounicode != NULL && pdfi_type_of(tounicode) != PDF_CMAP)) { |
278 | 1.68k | pdfi_countdown(tounicode); |
279 | 1.68k | tounicode = NULL; |
280 | 1.68k | code = 0; |
281 | 1.68k | } |
282 | 5.24k | } |
283 | 0 | else { |
284 | 0 | tounicode = NULL; |
285 | 0 | } |
286 | | |
287 | 5.24k | if (descpfont == NULL) { |
288 | 4.67k | gs_font *pf; |
289 | | |
290 | 4.67k | code = pdfi_load_font(ctx, stream_dict, page_dict, decfontdict, &pf, true); |
291 | 4.67k | if (code < 0) |
292 | 1.20k | goto error; |
293 | 3.46k | descpfont = (pdf_font *)pf->client_data; |
294 | 3.46k | } |
295 | | |
296 | 4.04k | if (descpfont->pdfi_font_type < e_pdf_cidfont_type0 || descpfont->pdfi_font_type > e_pdf_cidfont_type4) { |
297 | 12 | code = gs_note_error(gs_error_invalidfont); |
298 | 12 | goto error; |
299 | 12 | } |
300 | | |
301 | 4.03k | if (descpfont != NULL && ((pdf_cidfont_t *)descpfont)->substitute) { |
302 | 1.54k | pdf_obj *csi = NULL; |
303 | 1.54k | pdf_string *reg = NULL, *ord = NULL; |
304 | 1.54k | char *r = NULL, *o = NULL; |
305 | 1.54k | int rlen = 0, olen = 0; |
306 | | |
307 | 1.54k | code = pdfi_dict_get(ctx, decfontdict, "CIDSystemInfo", (pdf_obj **)&csi); |
308 | 1.54k | if (code >= 0) { |
309 | 1.54k | (void)pdfi_dict_get(ctx, (pdf_dict *)csi, "Registry", (pdf_obj **)®); |
310 | 1.54k | (void)pdfi_dict_get(ctx, (pdf_dict *)csi, "Ordering", (pdf_obj **)&ord); |
311 | 1.54k | if (reg != NULL && pdfi_type_of(reg) == PDF_STRING |
312 | 1.54k | && ord != NULL && pdfi_type_of(ord) == PDF_STRING) { |
313 | 1.53k | r = (char *)reg->data; |
314 | 1.53k | rlen = reg->length; |
315 | 1.53k | o = (char *)ord->data; |
316 | 1.53k | olen = ord->length; |
317 | 1.53k | } |
318 | 1.54k | pdfi_countdown(csi); |
319 | 1.54k | pdfi_countdown(reg); |
320 | 1.54k | pdfi_countdown(ord); |
321 | 1.54k | } |
322 | 1.54k | if (r == NULL || o == NULL) { |
323 | 8 | r = (char *)pcmap->csi_reg.data; |
324 | 8 | rlen = pcmap->csi_reg.size; |
325 | 8 | o = (char *)pcmap->csi_ord.data; |
326 | 8 | olen = pcmap->csi_ord.size; |
327 | 8 | } |
328 | 1.54k | if (rlen > 0 && olen > 0) |
329 | 1.54k | pdfi_font0_cid_subst_tables(r, rlen, o, olen, &dec, &substnwp); |
330 | 0 | else { |
331 | 0 | dec = NULL; |
332 | 0 | substnwp = NULL; |
333 | 0 | } |
334 | 1.54k | } |
335 | | /* reference is now owned by the descendent font created above */ |
336 | 4.03k | pdfi_countdown(decfontdict); |
337 | 4.03k | decfontdict = NULL; |
338 | 4.03k | if (code < 0) { |
339 | 2 | code = gs_note_error(gs_error_invalidfont); |
340 | 2 | goto error; |
341 | 2 | } |
342 | | /* If we're got this far, we have a CMap and a descendant font, let's make the Type 0 */ |
343 | 4.02k | pdft0 = (pdf_font_type0 *)gs_alloc_bytes(ctx->memory, sizeof(pdf_font_type0), "pdfi (type0 pdf_font)"); |
344 | 4.02k | if (pdft0 == NULL) { |
345 | 0 | code = gs_note_error(gs_error_VMerror); |
346 | 0 | goto error; |
347 | 0 | } |
348 | 4.02k | code = pdfi_array_alloc(ctx, 1, &arr); |
349 | 4.02k | if (code < 0) { |
350 | 0 | gs_free_object(ctx->memory, pdft0, "pdfi_read_type0_font(pdft0)"); |
351 | 0 | goto error; |
352 | 0 | } |
353 | 4.02k | arr->refcnt = 1; |
354 | 4.02k | code = pdfi_array_put(ctx, arr, 0, (pdf_obj *)descpfont); |
355 | 4.02k | if (code < 0) { |
356 | 0 | gs_free_object(ctx->memory, pdft0, "pdfi_read_type0_font(pdft0)"); |
357 | 0 | goto error; |
358 | 0 | } |
359 | | |
360 | 4.02k | pdft0->type = PDF_FONT; |
361 | 4.02k | pdft0->pdfi_font_type = e_pdf_font_type0; |
362 | 4.02k | pdft0->ctx = ctx; |
363 | | #if REFCNT_DEBUG |
364 | | pdft0->UID = ctx->UID++; |
365 | | dmprintf2(ctx->memory, "Allocated object of type %c with UID %"PRIi64"\n", pdft0->type, pdft0->UID); |
366 | | #endif |
367 | 4.02k | pdft0->refcnt = 1; |
368 | 4.02k | pdft0->filename = NULL; |
369 | 4.02k | pdft0->object_num = font_dict->object_num; |
370 | 4.02k | pdft0->generation_num = font_dict->generation_num; |
371 | 4.02k | pdft0->indirect_num = font_dict->indirect_num; |
372 | 4.02k | pdft0->indirect_gen = font_dict->indirect_gen; |
373 | 4.02k | pdft0->Encoding = (pdf_obj *)pcmap; |
374 | 4.02k | pdft0->ToUnicode = tounicode; |
375 | 4.02k | tounicode = NULL; |
376 | 4.02k | pdft0->DescendantFonts = arr; |
377 | 4.02k | pdft0->PDF_font = font_dict; |
378 | 4.02k | pdfi_countup(font_dict); |
379 | 4.02k | pdft0->FontDescriptor = fontdesc; |
380 | 4.02k | fontdesc = NULL; |
381 | 4.02k | pdft0->BaseFont = basefont; |
382 | 4.02k | pdft0->decoding = dec; |
383 | 4.02k | pdft0->substnwp = substnwp; |
384 | | |
385 | | /* Ownership transferred to pdft0, if we jump to error |
386 | | * these will now be freed by counting down pdft0. |
387 | | */ |
388 | 4.02k | tounicode = NULL; |
389 | 4.02k | arr = NULL; |
390 | 4.02k | basefont = NULL; |
391 | | |
392 | 4.02k | pdft0->pfont = NULL; /* In case we error out */ |
393 | | |
394 | 4.02k | pfont0 = (gs_font_type0 *)gs_alloc_struct(ctx->memory, gs_font, &st_gs_font_type0, "pdfi gs type 0 font"); |
395 | 4.02k | if (pfont0 == NULL) { |
396 | 0 | gs_free_object(ctx->memory, pdft0, "pdfi_read_type0_font(pdft0)"); |
397 | 0 | code = gs_note_error(gs_error_VMerror); |
398 | 0 | goto error; |
399 | 0 | } |
400 | 4.02k | gs_make_identity(&pfont0->orig_FontMatrix); |
401 | 4.02k | gs_make_identity(&pfont0->FontMatrix); |
402 | 4.02k | pfont0->next = pfont0->prev = 0; |
403 | 4.02k | pfont0->memory = ctx->memory; |
404 | 4.02k | pfont0->dir = ctx->font_dir; |
405 | 4.02k | pfont0->is_resource = false; |
406 | 4.02k | gs_notify_init(&pfont0->notify_list, ctx->memory); |
407 | 4.02k | pfont0->id = gs_next_ids(ctx->memory, 1); |
408 | 4.02k | pfont0->base = (gs_font *) pfont0; |
409 | 4.02k | pfont0->client_data = pdft0; |
410 | 4.02k | pfont0->WMode = pcmap->wmode; |
411 | 4.02k | pfont0->FontType = ft_composite; |
412 | 4.02k | pfont0->PaintType = 0; |
413 | 4.02k | pfont0->StrokeWidth = 0; |
414 | 4.02k | pfont0->is_cached = 0; |
415 | 4.02k | if (pdft0->BaseFont != NULL) { |
416 | 4.01k | pdf_name *nobj = (pdf_name *)pdft0->BaseFont; |
417 | 4.01k | nlen = nobj->length > gs_font_name_max ? gs_font_name_max : nobj->length; |
418 | | |
419 | 4.01k | memcpy(pfont0->key_name.chars, nobj->data, nlen); |
420 | 4.01k | pfont0->key_name.size = nlen; |
421 | 4.01k | memcpy(pfont0->font_name.chars, nobj->data, nlen); |
422 | 4.01k | pfont0->font_name.size = nlen; |
423 | 4.01k | } |
424 | 11 | else { |
425 | 11 | nlen = descpfont->pfont->key_name.size > gs_font_name_max ? gs_font_name_max : descpfont->pfont->key_name.size; |
426 | | |
427 | 11 | memcpy(pfont0->key_name.chars, descpfont->pfont->key_name.chars, nlen); |
428 | 11 | pfont0->key_name.size = nlen; |
429 | 11 | memcpy(pfont0->font_name.chars, descpfont->pfont->font_name.chars, nlen); |
430 | 11 | pfont0->font_name.size = nlen; |
431 | 11 | } |
432 | | |
433 | 4.02k | if (pcmap->name.size > 0) { |
434 | 4.02k | if (pfont0->key_name.size + pcmap->name.size + 1 < gs_font_name_max) { |
435 | 3.90k | memcpy(pfont0->key_name.chars + pfont0->key_name.size, "-", 1); |
436 | 3.90k | memcpy(pfont0->key_name.chars + pfont0->key_name.size + 1, pcmap->name.data, pcmap->name.size); |
437 | 3.90k | pfont0->key_name.size += pcmap->name.size + 1; |
438 | 3.90k | } |
439 | 4.02k | if (pfont0->font_name.size + pcmap->name.size + 1 < gs_font_name_max) { |
440 | 3.90k | memcpy(pfont0->font_name.chars + pfont0->font_name.size, "-", 1); |
441 | 3.90k | memcpy(pfont0->font_name.chars + pfont0->font_name.size + 1, pcmap->name.data, pcmap->name.size); |
442 | 3.90k | pfont0->font_name.size += pcmap->name.size + 1; |
443 | 3.90k | } |
444 | 4.02k | } |
445 | 4.02k | pfont0->procs.define_font = gs_no_define_font; |
446 | 4.02k | pfont0->procs.make_font = gs_no_make_font; |
447 | 4.02k | pfont0->procs.font_info = gs_default_font_info; |
448 | 4.02k | pfont0->procs.same_font = gs_default_same_font; |
449 | 4.02k | pfont0->procs.encode_char = pdfi_encode_char; |
450 | 4.02k | pfont0->procs.decode_glyph = pdfi_font0_map_glyph_to_unicode; |
451 | 4.02k | pfont0->procs.enumerate_glyph = gs_no_enumerate_glyph; |
452 | 4.02k | pfont0->procs.glyph_info = gs_default_glyph_info; |
453 | 4.02k | pfont0->procs.glyph_outline = gs_no_glyph_outline; |
454 | 4.02k | pfont0->procs.glyph_name = pdfi_font0_glyph_name; |
455 | 4.02k | pfont0->procs.init_fstack = gs_type0_init_fstack; |
456 | 4.02k | pfont0->procs.next_char_glyph = gs_type0_next_char_glyph; |
457 | 4.02k | pfont0->procs.build_char = gs_no_build_char; |
458 | | |
459 | 4.02k | pfont0->data.FMapType = fmap_CMap; |
460 | 4.02k | pfont0->data.EscChar = 0xff; |
461 | 4.02k | pfont0->data.ShiftIn = 0x0f; |
462 | 4.02k | pfont0->data.SubsVector.data = NULL; |
463 | 4.02k | pfont0->data.SubsVector.size = 0; |
464 | 4.02k | pfont0->data.subs_size = pfont0->data.subs_width = 0; |
465 | | |
466 | 4.02k | pfont0->data.Encoding = (uint *)gs_alloc_bytes(ctx->memory, sizeof(uint), "pdfi_read_type0_font Encoding"); |
467 | 4.02k | if (pfont0->data.Encoding == NULL) { |
468 | 0 | gs_free_object(ctx->memory, pfont0, "pdfi_read_type0_font(pfont0)"); |
469 | 0 | code = gs_note_error(gs_error_VMerror); |
470 | 0 | goto error; |
471 | 0 | } |
472 | 4.02k | *pfont0->data.Encoding = 0; |
473 | | |
474 | 4.02k | pfont0->data.encoding_size = 1; |
475 | 4.02k | pfont0->data.FDepVector = (gs_font **)gs_alloc_bytes(ctx->memory, sizeof(gs_font *), "pdfi_read_type0_font FDepVector"); |
476 | 4.02k | if (pfont0->data.FDepVector == NULL) { |
477 | | /* We transferred ownership of pcmap to pfont0 above, but we didn't null the pointer |
478 | | * so we could keep using it. We must NULL it out before returning an error to prevent |
479 | | * reference counting problems. |
480 | | */ |
481 | 0 | pcmap = NULL; |
482 | 0 | gs_free_object(ctx->memory, pfont0, "pdfi_read_type0_font(pfont0)"); |
483 | 0 | code = gs_note_error(gs_error_VMerror); |
484 | 0 | goto error; |
485 | 0 | } |
486 | 4.02k | *pfont0->data.FDepVector = (gs_font *)descpfont->pfont; |
487 | 4.02k | pdfi_countdown(descpfont); |
488 | 4.02k | descpfont = NULL; |
489 | 4.02k | pfont0->data.fdep_size = 1; |
490 | 4.02k | pfont0->data.CMap = (gs_cmap_t *)pcmap->gscmap; |
491 | | |
492 | | /* NULL he pointer to prevent any reference counting problems, ownership was |
493 | | * transferred to pfont0, but we maintained the pointer for easy access until this |
494 | | * point. |
495 | | */ |
496 | 4.02k | pcmap = NULL; |
497 | | |
498 | 4.02k | pdft0->pfont = (gs_font_base *)pfont0; |
499 | | |
500 | 4.02k | code = gs_definefont(ctx->font_dir, (gs_font *)pdft0->pfont); |
501 | 4.02k | if (code < 0) { |
502 | 0 | gs_free_object(ctx->memory, pfont0, "pdfi_read_type0_font(pfont0)"); |
503 | 0 | code = gs_note_error(gs_error_VMerror); |
504 | 0 | goto error; |
505 | 0 | } |
506 | | |
507 | | /* object_num can be zero if the dictionary was defined inline */ |
508 | 4.02k | if (pdft0->object_num != 0) { |
509 | 4.02k | (void)replace_cache_entry(ctx, (pdf_obj *)pdft0); |
510 | 4.02k | } |
511 | | |
512 | 4.02k | *ppdffont = (pdf_font *)pdft0; |
513 | 4.02k | return 0; |
514 | | |
515 | 2.82k | error: |
516 | 2.82k | pdfi_countdown(arr); |
517 | 2.82k | pdfi_countdown(pcmap); |
518 | 2.82k | pdfi_countdown(tounicode); |
519 | 2.82k | pdfi_countdown(basefont); |
520 | 2.82k | pdfi_countdown(decfontdict); |
521 | 2.82k | pdfi_countdown(dfontdesc); |
522 | 2.82k | pdfi_countdown(fontdesc); |
523 | 2.82k | pdfi_countdown(ffile); |
524 | 2.82k | pdfi_countdown(descpfont); |
525 | 2.82k | pdfi_countdown(pdft0); |
526 | | |
527 | 2.82k | return code; |
528 | 4.02k | } |
529 | | |
530 | | int |
531 | | pdfi_free_font_type0(pdf_obj *font) |
532 | 4.02k | { |
533 | 4.02k | pdf_font_type0 *pdft0 = (pdf_font_type0 *)font; |
534 | 4.02k | gs_font_type0 *pfont0 = (gs_font_type0 *)pdft0->pfont; |
535 | 4.02k | pdfi_countdown(pdft0->PDF_font); |
536 | 4.02k | pdfi_countdown(pdft0->BaseFont); |
537 | 4.02k | pdfi_countdown(pdft0->FontDescriptor); |
538 | 4.02k | pdfi_countdown(pdft0->Encoding); |
539 | 4.02k | pdfi_countdown(pdft0->DescendantFonts); |
540 | 4.02k | pdfi_countdown(pdft0->ToUnicode); |
541 | 4.02k | pdfi_countdown(pdft0->filename); |
542 | | |
543 | 4.02k | gs_free_object(OBJ_MEMORY(pdft0), pfont0->data.Encoding, "pdfi_free_font_type0(data.Encoding)"); |
544 | | /* We shouldn't need to free the fonts in the FDepVector, that should happen |
545 | | with DescendantFonts above. |
546 | | */ |
547 | 4.02k | gs_free_object(OBJ_MEMORY(pdft0), pfont0->data.FDepVector, "pdfi_free_font_type0(data.FDepVector)"); |
548 | 4.02k | gs_free_object(OBJ_MEMORY(pdft0), pfont0, "pdfi_free_font_type0(pfont0)"); |
549 | 4.02k | gs_free_object(OBJ_MEMORY(pdft0), pdft0, "pdfi_free_font_type0(pdft0)"); |
550 | | |
551 | 4.02k | return 0; |
552 | 4.02k | } |