/src/ghostpdl/pdf/pdf_fontps.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 | | /* common code for Postscript-type font handling */ |
17 | | #include "scanchar.h" |
18 | | #include "sfilter.h" |
19 | | #include "stream.h" |
20 | | #include "strimpl.h" |
21 | | |
22 | | #include "pdf_int.h" |
23 | | #include "pdf_types.h" |
24 | | #include "pdf_array.h" |
25 | | #include "pdf_dict.h" |
26 | | #include "pdf_font.h" |
27 | | #include "pdf_font_types.h" |
28 | | #include "pdf_fontps.h" |
29 | | |
30 | | static const char *const notdefnamestr = ".notdef"; |
31 | | |
32 | | int |
33 | | pdfi_pscript_stack_init(pdf_context *pdfi_ctx, pdf_ps_oper_list_t *ops, void *client_data, |
34 | | pdf_ps_ctx_t *s) |
35 | 146k | { |
36 | 146k | int i, size = PDF_PS_STACK_SIZE; |
37 | 146k | int initsizebytes = sizeof(pdf_ps_stack_object_t) * PDF_PS_STACK_SIZE; |
38 | 146k | s->pdfi_ctx = pdfi_ctx; |
39 | 146k | s->ops = ops; |
40 | 146k | s->client_data = client_data; |
41 | | |
42 | 146k | s->stack = (pdf_ps_stack_object_t *)gs_alloc_bytes(pdfi_ctx->memory, initsizebytes, "pdfi_pscript_stack_init(stack)"); |
43 | 146k | if (s->stack == NULL) |
44 | 0 | return_error(gs_error_VMerror); |
45 | | |
46 | 146k | s->cur = s->stack + 1; |
47 | 146k | s->toplim = s->cur + size; |
48 | | |
49 | 293k | for (i = 0; i < PDF_PS_STACK_GUARDS; i++) |
50 | 146k | s->stack[i].type = PDF_PS_OBJ_STACK_BOTTOM; |
51 | | |
52 | 293k | for (i = 0; i < PDF_PS_STACK_GUARDS; i++) |
53 | 146k | s->stack[size - 1 + i].type = PDF_PS_OBJ_STACK_TOP; |
54 | | |
55 | 52.8M | for (i = 0; i < size - 1; i++) { |
56 | 52.6M | pdf_ps_make_null(&(s->cur[i])); |
57 | 52.6M | } |
58 | 146k | return 0; |
59 | 146k | } |
60 | | |
61 | | void |
62 | | pdfi_pscript_stack_finit(pdf_ps_ctx_t *s) |
63 | 146k | { |
64 | 146k | int stackdepth; |
65 | | |
66 | 146k | if ((stackdepth = pdf_ps_stack_count(s)) > 0) { |
67 | 0 | pdf_ps_stack_pop(s, stackdepth); |
68 | 0 | } |
69 | 146k | gs_free_object(s->pdfi_ctx->memory, s->stack, "pdfi_pscript_stack_finit(stack)"); |
70 | 146k | } |
71 | | |
72 | | int |
73 | | ps_pdf_null_oper_func(gs_memory_t *mem, pdf_ps_ctx_t *stack, byte *buf, byte *bufend) |
74 | 3.28M | { |
75 | 3.28M | return 0; |
76 | 3.28M | } |
77 | | |
78 | | int |
79 | | clear_stack_oper_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
80 | 212k | { |
81 | 212k | int depth = s->cur - &(s->stack[1]); |
82 | | |
83 | 212k | return pdf_ps_stack_pop(s, depth); |
84 | 212k | } |
85 | | |
86 | | int |
87 | | pdf_ps_pop_oper_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
88 | 330k | { |
89 | 330k | return pdf_ps_stack_pop(s, 1); |
90 | 330k | } |
91 | | |
92 | | int |
93 | | pdf_ps_pop_and_pushmark_func(gs_memory_t *mem, pdf_ps_ctx_t *stack, byte *buf, byte *bufend) |
94 | 282k | { |
95 | 282k | int code = pdf_ps_stack_pop(stack, 1); |
96 | | |
97 | 282k | if (code >= 0) |
98 | 282k | code = pdf_ps_stack_push_mark(stack); |
99 | 282k | return code; |
100 | 282k | } |
101 | | |
102 | | static inline int |
103 | | pdf_ps_is_whitespace(int c) |
104 | 761M | { |
105 | 761M | return (c == 0x20) || (c == 0x9) || (c == 0xD) || (c == 0xA); |
106 | 761M | } |
107 | | |
108 | | static inline int |
109 | | pdf_ps_end_object(int c) |
110 | 761M | { |
111 | 761M | return pdf_ps_is_whitespace(c) || (c == '/') || (c == '[') || (c == ']') || c == '{' || c == '}' || (c == '(') || (c == '<'); |
112 | 761M | } |
113 | | |
114 | | static inline int |
115 | | pdf_ps_end_number_object(int c) |
116 | 251M | { |
117 | 251M | return (c != '.' && c != 'e' && c != '-' && (c < '0' || c > '9')); |
118 | 251M | } |
119 | | |
120 | | int |
121 | | pdfi_pscript_interpret(pdf_ps_ctx_t *cs, byte *pdfpsbuf, int64_t buflen) |
122 | 146k | { |
123 | 146k | int code = 0; |
124 | 146k | byte *buflim = pdfpsbuf + buflen; |
125 | 146k | int arraydepth = 0; |
126 | 146k | int stackdepth; |
127 | | |
128 | 444M | while (pdfpsbuf < buflim && code >= 0) { |
129 | 444M | switch (*pdfpsbuf++) { |
130 | 323k | case '%': /* Comment */ |
131 | 323k | { |
132 | 16.1M | while (pdfpsbuf < buflim && *pdfpsbuf != char_EOL && *pdfpsbuf != '\f' && |
133 | 16.1M | *pdfpsbuf != char_CR) |
134 | 15.8M | pdfpsbuf++; |
135 | | |
136 | 323k | if (pdfpsbuf < buflim && *pdfpsbuf == char_EOL) |
137 | 317k | pdfpsbuf++; |
138 | 323k | } |
139 | 323k | break; |
140 | 46.7M | case '/': /* name */ |
141 | 46.7M | { |
142 | 46.7M | byte *n = pdfpsbuf; |
143 | 46.7M | int len; |
144 | | |
145 | 393M | while (pdfpsbuf < buflim && !pdf_ps_end_object((int)*pdfpsbuf)) |
146 | 346M | pdfpsbuf++; |
147 | 46.7M | len = pdfpsbuf - n; |
148 | 46.7M | code = pdf_ps_stack_push_name(cs, n, len); |
149 | 46.7M | } break; |
150 | 566k | case '(': /* string */ |
151 | 566k | { |
152 | 566k | byte *s = pdfpsbuf; |
153 | 566k | int len; |
154 | 566k | int depth = 1; |
155 | | |
156 | 54.0M | while (pdfpsbuf < buflim && depth > 0) { |
157 | 53.4M | if (*pdfpsbuf == '(') { |
158 | 364k | depth++; |
159 | 364k | } |
160 | 53.1M | else if (*pdfpsbuf == ')') { |
161 | 904k | depth--; |
162 | 904k | } |
163 | 53.4M | pdfpsbuf++; |
164 | 53.4M | } |
165 | 566k | len = (pdfpsbuf - s) - 1; |
166 | 566k | code = pdf_ps_stack_push_string(cs, s, len); |
167 | 566k | } |
168 | 566k | break; |
169 | 29.8M | case '<': /* hex string */ |
170 | 29.8M | { |
171 | 29.8M | byte *s = pdfpsbuf; |
172 | 29.8M | stream_cursor_read pr; |
173 | 29.8M | stream_cursor_write pw; |
174 | 29.8M | int odd_digit = -1; |
175 | | |
176 | 29.8M | if (pdfpsbuf < buflim && *pdfpsbuf == '<') { /* Dict opening "<<" - we don't care */ |
177 | 34.5k | pdfpsbuf++; |
178 | 34.5k | continue; |
179 | 34.5k | } |
180 | 159M | while (pdfpsbuf < buflim && *pdfpsbuf != '>') |
181 | 130M | pdfpsbuf++; |
182 | | |
183 | 29.8M | pr.ptr = s - 1; |
184 | 29.8M | pr.limit = pdfpsbuf - 1; |
185 | 29.8M | pw.ptr = s - 1; |
186 | 29.8M | pw.limit = pdfpsbuf - 1; |
187 | 29.8M | code = s_hex_process(&pr, &pw, &odd_digit, hex_ignore_garbage); |
188 | 29.8M | if (code != ERRC && pw.ptr - (s - 1) > 0) { |
189 | 29.8M | code = pdf_ps_stack_push_string(cs, s, pw.ptr - (s - 1)); |
190 | 29.8M | } |
191 | 29.8M | } |
192 | 0 | break; |
193 | 29.9M | case '>': /* For hex strings, this should be handled above */ |
194 | 29.9M | { |
195 | 29.9M | if (pdfpsbuf < buflim && *pdfpsbuf == '>') { /* Dict closing "<<" - we still don't care */ |
196 | 42.6k | pdfpsbuf++; |
197 | 42.6k | } |
198 | 29.9M | } |
199 | 29.9M | break; |
200 | 639k | case '[':; /* begin array */ |
201 | 2.19M | case '{':; /* begin executable array (mainly, FontBBox) */ |
202 | 2.19M | arraydepth++; |
203 | 2.19M | code = pdf_ps_stack_push_arr_mark(cs); |
204 | 2.19M | break; |
205 | 629k | case ']': /* end array */ |
206 | 2.18M | case '}': /* end executable array */ |
207 | 2.18M | { |
208 | 2.18M | pdf_ps_stack_object_t *arr = NULL; |
209 | 2.18M | int i, size = pdf_ps_stack_count_to_mark(cs, PDF_PS_OBJ_ARR_MARK); |
210 | | |
211 | 2.18M | if (size > 0 && arraydepth > 0) { |
212 | 1.53M | arr = (pdf_ps_stack_object_t *) gs_alloc_bytes(cs->pdfi_ctx->memory, size * sizeof(pdf_ps_stack_object_t), "pdfi_pscript_interpret(pdf_ps_stack_object_t"); |
213 | 1.53M | if (arr == NULL) { |
214 | 0 | code = gs_note_error(gs_error_VMerror); |
215 | | /* clean up the stack, including the mark object */ |
216 | 0 | (void)pdf_ps_stack_pop(cs, size + 1); |
217 | 0 | size = 0; |
218 | 0 | } |
219 | 1.53M | else { |
220 | 6.96M | for (i = 0; i < size; i++) { |
221 | 5.42M | memcpy(&(arr[(size - 1) - i]), cs->cur, sizeof(*cs->cur)); |
222 | 5.42M | if (pdf_ps_obj_has_type(cs->cur, PDF_PS_OBJ_ARRAY)) { |
223 | 1.00M | pdf_ps_make_null(cs->cur); |
224 | 1.00M | } |
225 | 5.42M | (void)pdf_ps_stack_pop(cs, 1); |
226 | 5.42M | } |
227 | | /* And pop the array mark */ |
228 | 1.53M | (void)pdf_ps_stack_pop(cs, 1); |
229 | 1.53M | } |
230 | 1.53M | } |
231 | 649k | else { |
232 | | /* And pop the array mark for an emtpy array */ |
233 | 649k | (void)pdf_ps_stack_pop(cs, 1); |
234 | 649k | } |
235 | 2.18M | code = pdf_ps_stack_push_array(cs, arr, size > 0 ? size : 0); |
236 | 2.18M | arraydepth--; |
237 | 2.18M | if (arraydepth < 0) |
238 | 19.1k | arraydepth = 0; |
239 | 2.18M | } |
240 | 2.18M | break; |
241 | 7.29k | case '.': |
242 | 386k | case '-': |
243 | 6.56M | case '+': |
244 | 7.48M | case '0': |
245 | 28.9M | case '1': |
246 | 36.6M | case '2': |
247 | 41.2M | case '3': |
248 | 46.6M | case '4': |
249 | 53.4M | case '5': |
250 | 58.2M | case '6': |
251 | 61.9M | case '7': |
252 | 65.2M | case '8': |
253 | 68.8M | case '9':{ |
254 | 68.8M | bool is_float = false; |
255 | 68.8M | int len; |
256 | 68.8M | byte *n = --pdfpsbuf, *numbuf; |
257 | | |
258 | 251M | while (pdfpsbuf < buflim && !pdf_ps_end_number_object((int)*pdfpsbuf)) { |
259 | 182M | if (*pdfpsbuf == '.' || *pdfpsbuf == 'e') |
260 | 540k | is_float = true; |
261 | 182M | pdfpsbuf++; |
262 | 182M | } |
263 | 68.8M | len = pdfpsbuf - n; |
264 | 68.8M | if (len == 1 && *n == '-') { |
265 | | /* Not a number, might be an operator */ |
266 | 84.2k | pdfpsbuf = n + 1; |
267 | 84.2k | goto retry_as_oper; |
268 | 84.2k | } |
269 | 68.7M | numbuf = gs_alloc_bytes(cs->pdfi_ctx->memory, len + 1, "ps pdf number buffer"); |
270 | 68.7M | if (numbuf == NULL) { |
271 | 0 | code = gs_note_error(gs_error_VMerror); |
272 | 0 | } |
273 | 68.7M | else { |
274 | 68.7M | memcpy(numbuf, n, len); |
275 | 68.7M | numbuf[len] = '\0'; |
276 | 68.7M | if (is_float) { |
277 | 540k | float f = (float)atof((const char *)numbuf); |
278 | | |
279 | 540k | code = pdf_ps_stack_push_float(cs, f); |
280 | 540k | } |
281 | 68.2M | else { |
282 | 68.2M | int i = atoi((const char *)numbuf); |
283 | | |
284 | 68.2M | code = pdf_ps_stack_push_int(cs, i); |
285 | 68.2M | } |
286 | 68.7M | gs_free_object(cs->pdfi_ctx->memory, numbuf, "ps pdf number buffer"); |
287 | 68.7M | } |
288 | 68.7M | } break; |
289 | 110M | case ' ': |
290 | 110M | case '\f': |
291 | 110M | case '\t': |
292 | 111M | case char_CR: |
293 | 162M | case char_EOL: |
294 | 162M | case char_NULL: |
295 | 162M | break; |
296 | 100M | default: |
297 | 100M | retry_as_oper:{ |
298 | 100M | byte *n = --pdfpsbuf; |
299 | 100M | int len, i; |
300 | 100M | int (*opfunc)(gs_memory_t *mem, pdf_ps_ctx_t *stack, byte *buf, byte *bufend) = NULL; |
301 | 100M | pdf_ps_oper_list_t *ops = cs->ops; |
302 | | |
303 | 368M | while (pdfpsbuf < buflim && !pdf_ps_end_object((int)*pdfpsbuf)) |
304 | 268M | pdfpsbuf++; |
305 | | |
306 | 100M | if (arraydepth == 0) { |
307 | 96.6M | len = pdfpsbuf - n; |
308 | 1.27G | for (i = 0; ops[i].opname != NULL; i++) { |
309 | 1.23G | if (len == ops[i].opnamelen && !memcmp(n, ops[i].opname, len)) { |
310 | 51.9M | opfunc = ops[i].oper; |
311 | 51.9M | break; |
312 | 51.9M | } |
313 | 1.23G | } |
314 | | |
315 | 96.6M | if (opfunc) { |
316 | 51.9M | code = (*opfunc) (cs->pdfi_ctx->memory, cs, pdfpsbuf, buflim); |
317 | 51.9M | if (code > 0) { |
318 | 43.2M | pdfpsbuf += code; |
319 | 43.2M | code = 0; |
320 | 43.2M | } |
321 | 51.9M | } |
322 | 96.6M | } |
323 | 100M | } |
324 | 100M | break; |
325 | 444M | } |
326 | 444M | } |
327 | 146k | if ((stackdepth = pdf_ps_stack_count(cs)) > 0) { |
328 | 12.5k | pdf_ps_stack_pop(cs, stackdepth); |
329 | 12.5k | } |
330 | 146k | return code; |
331 | 146k | } |
332 | | |
333 | | static inline bool pdf_ps_name_cmp(pdf_ps_stack_object_t *obj, const char *namestr) |
334 | 3.96M | { |
335 | 3.96M | byte *d = NULL; |
336 | 3.96M | int l1, l2; |
337 | | |
338 | 3.96M | if (namestr) { |
339 | 3.96M | l2 = strlen(namestr); |
340 | 3.96M | } |
341 | | |
342 | 3.96M | if (obj->type == PDF_PS_OBJ_NAME) { |
343 | 3.96M | d = obj->val.name; |
344 | 3.96M | l1 = obj->size; |
345 | 3.96M | } |
346 | 0 | else if (obj->type == PDF_PS_OBJ_STRING) { |
347 | 0 | d = obj->val.name; |
348 | 0 | l1 = obj->size; |
349 | 0 | } |
350 | 3.96M | if (d != NULL && namestr != NULL && l1 == l2) { |
351 | 3.96M | return memcmp(d, namestr, l1) == 0 ? true : false; |
352 | 3.96M | } |
353 | 0 | return false; |
354 | 3.96M | } |
355 | | |
356 | | static int |
357 | | ps_font_def_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
358 | 1.93M | { |
359 | 1.93M | int code = 0, code2 = 0; |
360 | 1.93M | ps_font_interp_private *priv = (ps_font_interp_private *) s->client_data; |
361 | | |
362 | 1.93M | if ((code = pdf_ps_stack_count(s)) < 2) { |
363 | 939 | return pdf_ps_stack_pop(s, code); |
364 | 939 | } |
365 | | |
366 | 1.93M | if (pdf_ps_obj_has_type(&s->cur[-1], PDF_PS_OBJ_NAME)) { |
367 | 1.86M | switch (s->cur[-1].size) { |
368 | | |
369 | 259 | case 4: |
370 | 259 | if (pdf_ps_name_cmp(&s->cur[-1], "XUID")) { |
371 | 0 | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY) && uid_is_valid(&priv->gsu.gst1.UID) == false) { |
372 | 0 | int i, size = s->cur[0].size; |
373 | 0 | long *xvals = (long *)gs_alloc_bytes(mem, size *sizeof(long), "ps_font_def_func(xuid vals)"); |
374 | |
|
375 | 0 | if (xvals != NULL) { |
376 | 0 | for (i = 0; i < size; i++) { |
377 | 0 | if (pdf_ps_obj_has_type(&s->cur[0].val.arr[i], PDF_PS_OBJ_INTEGER)) { |
378 | 0 | xvals[i] = s->cur[0].val.arr[i].val.i; |
379 | 0 | } |
380 | 0 | else { |
381 | 0 | gs_free_object(mem, xvals, "ps_font_def_func(xuid vals)"); |
382 | 0 | xvals = NULL; |
383 | 0 | break; |
384 | 0 | } |
385 | 0 | } |
386 | 0 | } |
387 | 0 | if (xvals != NULL) { |
388 | 0 | if (priv->gsu.gst1.UID.xvalues != NULL) |
389 | 0 | gs_free_object(mem, priv->gsu.gst1.UID.xvalues, "ps_font_def_func(old xuid vals)"); |
390 | 0 | uid_set_XUID(&priv->gsu.gst1.UID, xvals, size); |
391 | 0 | } |
392 | 0 | } |
393 | 0 | } |
394 | 259 | break; |
395 | | |
396 | 128k | case 5: |
397 | 128k | if (pdf_ps_name_cmp(&s->cur[-1], "StdHW")) { |
398 | 61.4k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY) && s->cur[0].size > 0) { |
399 | 61.4k | if (pdf_ps_obj_has_type(&s->cur[0].val.arr[0], PDF_PS_OBJ_INTEGER)) { |
400 | 61.4k | priv->gsu.gst1.data.StdHW.values[0] = (float)s->cur[0].val.arr[0].val.i; |
401 | 61.4k | priv->gsu.gst1.data.StdHW.count = 1; |
402 | 61.4k | } |
403 | 32 | else if (pdf_ps_obj_has_type(&s->cur[0].val.arr[0], PDF_PS_OBJ_FLOAT)) { |
404 | 32 | priv->gsu.gst1.data.StdHW.values[0] = s->cur[0].val.arr[0].val.f; |
405 | 32 | priv->gsu.gst1.data.StdHW.count = 1; |
406 | 32 | } |
407 | 61.4k | } |
408 | 61.4k | } |
409 | 67.4k | else if (pdf_ps_name_cmp(&s->cur[-1], "StdVW")) { |
410 | 61.4k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY) && s->cur[0].size > 0) { |
411 | 61.4k | if (pdf_ps_obj_has_type(&s->cur[0].val.arr[0], PDF_PS_OBJ_INTEGER)) { |
412 | 61.4k | priv->gsu.gst1.data.StdVW.values[0] = (float)s->cur[0].val.arr[0].val.i; |
413 | 61.4k | priv->gsu.gst1.data.StdVW.count = 1; |
414 | 61.4k | } |
415 | 32 | else if (pdf_ps_obj_has_type(&s->cur[0].val.arr[0], PDF_PS_OBJ_FLOAT)) { |
416 | 32 | priv->gsu.gst1.data.StdVW.values[0] = s->cur[0].val.arr[0].val.f; |
417 | 32 | priv->gsu.gst1.data.StdVW.count = 1; |
418 | 32 | } |
419 | 61.4k | } |
420 | 61.4k | } |
421 | 5.95k | else if (pdf_ps_name_cmp(&s->cur[-1], "WMode")) { |
422 | 5.33k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) { |
423 | 5.33k | if (s->cur[0].val.i != 0) { |
424 | 2 | if (s->cur[0].val.i != 1) |
425 | 2 | pdfi_set_warning(s->pdfi_ctx, 0, NULL, W_PDF_BAD_WMODE, "ps_font_def_func", NULL); |
426 | 2 | priv->gsu.gst1.WMode = 1; |
427 | 2 | } |
428 | 5.33k | else |
429 | 5.33k | priv->gsu.gst1.WMode = 0; |
430 | 5.33k | } |
431 | 5.33k | } |
432 | 622 | else if (pdf_ps_name_cmp(&s->cur[-1], "lenIV")) { |
433 | 187 | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) { |
434 | 187 | priv->gsu.gst1.data.lenIV = s->cur[0].val.i; |
435 | 187 | } |
436 | 187 | } |
437 | 128k | break; |
438 | | |
439 | 132k | case 6: |
440 | 132k | if (pdf_ps_name_cmp(&s->cur[-1], "Notice") && priv->u.t1.notice == NULL) { |
441 | 65.3k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_STRING)) { |
442 | 65.3k | pdf_string *subr_str; |
443 | | |
444 | 65.3k | code = pdfi_object_alloc(s->pdfi_ctx, PDF_STRING, (unsigned int)s->cur[0].size, (pdf_obj **)&subr_str); |
445 | 65.3k | if (code < 0) { |
446 | 0 | return code; |
447 | 0 | } |
448 | 65.3k | pdfi_countup(subr_str); |
449 | 65.3k | memcpy(subr_str->data, s->cur[0].val.name, s->cur[0].size); |
450 | | |
451 | 65.3k | pdfi_countdown(priv->u.t1.notice); |
452 | 65.3k | priv->u.t1.notice = subr_str; |
453 | 65.3k | } |
454 | 65.3k | } |
455 | 132k | break; |
456 | 411k | case 8: |
457 | 411k | if (pdf_ps_name_cmp(&s->cur[-1], "FontName")) { |
458 | 66.7k | int fnlen = 0; |
459 | 66.7k | char *pname = NULL; |
460 | | |
461 | 66.7k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_NAME)) { |
462 | 66.6k | fnlen = s->cur[0].size > gs_font_name_max ? gs_font_name_max : s->cur[0].size; |
463 | 66.6k | pname = (char *)s->cur[0].val.name; |
464 | 66.6k | } |
465 | 37 | else if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_STRING)) { |
466 | 0 | fnlen = s->cur[0].size > gs_font_name_max ? gs_font_name_max : s->cur[0].size; |
467 | 0 | pname = (char *)s->cur[0].val.string; |
468 | 0 | } |
469 | 66.7k | if (pname && priv->gsu.gst1.key_name.chars[0] == '\0') { |
470 | 65.4k | memcpy(priv->gsu.gst1.key_name.chars, pname, fnlen); |
471 | 65.4k | priv->gsu.gst1.key_name.chars[fnlen] = '\0'; |
472 | 65.4k | priv->gsu.gst1.key_name.size = fnlen; |
473 | | |
474 | 65.4k | memcpy(priv->gsu.gst1.font_name.chars, pname, fnlen); |
475 | 65.4k | priv->gsu.gst1.font_name.chars[fnlen] = '\0'; |
476 | 65.4k | priv->gsu.gst1.font_name.size = fnlen; |
477 | 65.4k | } |
478 | 66.7k | } |
479 | 344k | else if (pdf_ps_name_cmp(&s->cur[-1], "FontBBox")) { |
480 | 64.9k | if (s->cur[0].size > 0 && pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY)) { |
481 | 64.9k | int i, j; |
482 | 64.9k | double bbox[4] = { 0, 0, 1000, 1000 }; |
483 | 64.9k | if (pdf_ps_obj_has_type(&s->cur[0].val.arr[0], PDF_PS_OBJ_ARRAY)) { /* This is (probably) a Blend/FontBBox entry */ |
484 | 0 | code = pdfi_array_alloc(s->pdfi_ctx, s->cur[0].size, &priv->u.t1.blendfontbbox); |
485 | 0 | if (code >= 0) { |
486 | 0 | pdfi_countup(priv->u.t1.blendfontbbox); |
487 | 0 | for (i = 0; i < s->cur[0].size; i++) { |
488 | 0 | pdf_ps_stack_object_t *arr = &s->cur[0].val.arr[i]; |
489 | 0 | pdf_array *parr = NULL; |
490 | 0 | pdf_num *n; |
491 | 0 | if (pdf_ps_obj_has_type(arr, PDF_PS_OBJ_ARRAY)) { |
492 | 0 | code = pdfi_array_alloc(s->pdfi_ctx, arr->size, &parr); |
493 | 0 | if (code < 0) |
494 | 0 | break; |
495 | 0 | pdfi_countup(parr); |
496 | |
|
497 | 0 | for (j = 0; j < arr->size; j++) { |
498 | 0 | if (pdf_ps_obj_has_type(&arr->val.arr[j], PDF_PS_OBJ_INTEGER)) { |
499 | 0 | code = pdfi_object_alloc(s->pdfi_ctx, PDF_INT, 0, (pdf_obj **)&n); |
500 | 0 | if (code >= 0) |
501 | 0 | n->value.i = arr->val.arr[j].val.i; |
502 | 0 | } |
503 | 0 | else if (pdf_ps_obj_has_type(&arr->val.arr[j], PDF_PS_OBJ_FLOAT)) { |
504 | 0 | code = pdfi_object_alloc(s->pdfi_ctx, PDF_REAL, 0, (pdf_obj **)&n); |
505 | 0 | if (code >= 0) |
506 | 0 | n->value.d = arr->val.arr[j].val.f; |
507 | 0 | } |
508 | 0 | else { |
509 | 0 | code = pdfi_object_alloc(s->pdfi_ctx, PDF_INT, 0, (pdf_obj **)&n); |
510 | 0 | if (code >= 0) |
511 | 0 | n->value.i = 0; |
512 | 0 | } |
513 | 0 | if (code < 0) |
514 | 0 | break; |
515 | 0 | pdfi_countup(n); |
516 | 0 | code = pdfi_array_put(s->pdfi_ctx, parr, j, (pdf_obj *)n); |
517 | 0 | pdfi_countdown(n); |
518 | 0 | if (code < 0) break; |
519 | 0 | } |
520 | 0 | } |
521 | 0 | if (code >= 0) |
522 | 0 | code = pdfi_array_put(s->pdfi_ctx, priv->u.t1.blendfontbbox, i, (pdf_obj *)parr); |
523 | 0 | pdfi_countdown(parr); |
524 | 0 | } |
525 | 0 | } |
526 | 0 | } |
527 | 64.9k | else if (s->cur[0].size >= 4) { |
528 | 324k | for (i = 0; i < 4; i++) { |
529 | 259k | if (pdf_ps_obj_has_type(&s->cur[0].val.arr[i], PDF_PS_OBJ_INTEGER)) { |
530 | 259k | bbox[i] = (double)s->cur[0].val.arr[i].val.i; |
531 | 259k | } |
532 | 15 | else if (pdf_ps_obj_has_type(&s->cur[0].val.arr[i], PDF_PS_OBJ_FLOAT)) { |
533 | 9 | bbox[i] = (double)s->cur[0].val.arr[i].val.f; |
534 | 9 | } |
535 | 259k | } |
536 | 64.9k | priv->gsu.gst1.FontBBox.p.x = bbox[0]; |
537 | 64.9k | priv->gsu.gst1.FontBBox.p.y = bbox[1]; |
538 | 64.9k | priv->gsu.gst1.FontBBox.q.x = bbox[2]; |
539 | 64.9k | priv->gsu.gst1.FontBBox.q.y = bbox[3]; |
540 | 64.9k | } |
541 | 64.9k | } |
542 | 64.9k | } |
543 | 279k | else if (pdf_ps_name_cmp(&s->cur[-1], "FontType")) { |
544 | 65.2k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) { |
545 | 65.2k | priv->gsu.gst1.FontType = s->cur[0].val.i; |
546 | 65.2k | priv->u.t1.pdfi_font_type = s->cur[0].val.i == 1 ? e_pdf_font_type1 : e_pdf_cidfont_type0; |
547 | 65.2k | } |
548 | 7 | else { |
549 | 7 | priv->gsu.gst1.FontType = 1; |
550 | 7 | priv->u.t1.pdfi_font_type = e_pdf_font_type1; |
551 | 7 | } |
552 | 65.2k | } |
553 | 214k | else if (pdf_ps_name_cmp(&s->cur[-1], "Encoding")) { |
554 | 66.6k | pdf_array *new_enc = NULL; |
555 | | |
556 | 66.6k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_NAME)) { |
557 | 55.8k | pdf_name *pname; |
558 | | |
559 | 55.8k | code = pdfi_name_alloc(s->pdfi_ctx, (byte *) s->cur[0].val.name, s->cur[0].size, (pdf_obj **) &pname); |
560 | 55.8k | if (code >= 0) { |
561 | 55.8k | pdfi_countup(pname); |
562 | | |
563 | 55.8k | code = pdfi_create_Encoding(s->pdfi_ctx, NULL, (pdf_obj *) pname, NULL, (pdf_obj **) &new_enc); |
564 | 55.8k | if (code >= 0) { |
565 | 55.8k | pdfi_countdown(priv->u.t1.Encoding); |
566 | 55.8k | priv->u.t1.Encoding = new_enc; |
567 | 55.8k | } |
568 | 55.8k | pdfi_countdown(pname); |
569 | 55.8k | } |
570 | 55.8k | } |
571 | 10.8k | else if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY)) { |
572 | 10.4k | int i; |
573 | | |
574 | 10.4k | code = pdfi_array_alloc(s->pdfi_ctx, s->cur[0].size, &new_enc); |
575 | 10.4k | if (code >= 0) { |
576 | 10.4k | pdfi_countup(new_enc); |
577 | 2.66M | for (i = 0; i < s->cur[0].size; i++) { |
578 | 2.65M | pdf_name *n = NULL; |
579 | 2.65M | byte *nm = (byte *) s->cur[0].val.arr[i].val.name; |
580 | 2.65M | int nlen = s->cur[0].val.arr[i].size; |
581 | | |
582 | 2.65M | code = pdfi_name_alloc(s->pdfi_ctx, (byte *) nm, nlen, (pdf_obj **) &n); |
583 | 2.65M | if (code < 0) |
584 | 0 | break; |
585 | 2.65M | pdfi_countup(n); |
586 | 2.65M | code = pdfi_array_put(s->pdfi_ctx, new_enc, (uint64_t) i, (pdf_obj *) n); |
587 | 2.65M | pdfi_countdown(n); |
588 | 2.65M | if (code < 0) |
589 | 0 | break; |
590 | 2.65M | } |
591 | 10.4k | if (code < 0) { |
592 | 0 | pdfi_countdown(new_enc); |
593 | 0 | } |
594 | 10.4k | else { |
595 | 10.4k | pdfi_countdown(priv->u.t1.Encoding); |
596 | 10.4k | priv->u.t1.Encoding = new_enc; |
597 | 10.4k | new_enc = NULL; |
598 | 10.4k | } |
599 | 10.4k | } |
600 | 10.4k | } |
601 | 66.6k | } |
602 | 147k | else if (pdf_ps_name_cmp(&s->cur[-1], "UniqueID") && uid_is_valid(&priv->gsu.gst1.UID) == false) { |
603 | | /* Ignore UniqueID if we already have a XUID */ |
604 | 14.4k | if (priv->gsu.gst1.UID.id >= 0) { |
605 | 14.4k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) { |
606 | 14.4k | uid_set_UniqueID(&priv->gsu.gst1.UID, s->cur[0].val.i); |
607 | 14.4k | } |
608 | 14.4k | } |
609 | 14.4k | } |
610 | 133k | else if (pdf_ps_name_cmp(&s->cur[-1], "FullName")) { |
611 | 65.4k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_STRING) && priv->u.t1.fullname == NULL) { |
612 | 65.4k | pdf_string *subr_str; |
613 | | |
614 | 65.4k | code = pdfi_object_alloc(s->pdfi_ctx, PDF_STRING, (unsigned int)s->cur[0].size, (pdf_obj **)&subr_str); |
615 | 65.4k | if (code < 0) { |
616 | 0 | return code; |
617 | 0 | } |
618 | 65.4k | pdfi_countup(subr_str); |
619 | 65.4k | memcpy(subr_str->data, s->cur[0].val.name, s->cur[0].size); |
620 | | |
621 | 65.4k | pdfi_countdown(priv->u.t1.fullname); |
622 | 65.4k | priv->u.t1.fullname = subr_str; |
623 | 65.4k | } |
624 | 65.4k | } |
625 | 411k | break; |
626 | | |
627 | 411k | case 9: |
628 | 367k | if (pdf_ps_name_cmp(&s->cur[-1], "PaintType")) { |
629 | 65.3k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) { |
630 | 65.3k | priv->gsu.gst1.PaintType = s->cur[0].val.i; |
631 | 65.3k | } |
632 | 65.3k | } |
633 | 302k | else if (pdf_ps_name_cmp(&s->cur[-1], "StemSnapH")) { |
634 | 61.3k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY)) { |
635 | 61.3k | int i, size = s->cur[0].size > 12 ? 12 : s->cur[0].size; |
636 | | |
637 | 692k | for (i = 0; i < size; i++) { |
638 | 630k | if (pdf_ps_obj_has_type(&s->cur[0].val.arr[i], PDF_PS_OBJ_INTEGER)) { |
639 | 630k | priv->gsu.gst1.data.StemSnapH.values[i] = (float)s->cur[0].val.arr[i].val.i; |
640 | 630k | } |
641 | 64 | else if (pdf_ps_obj_has_type(&s->cur[0].val.arr[i], PDF_PS_OBJ_FLOAT)) { |
642 | 64 | priv->gsu.gst1.data.StemSnapH.values[i] = s->cur[0].val.arr[i].val.f; |
643 | 64 | } |
644 | 630k | } |
645 | 61.3k | priv->gsu.gst1.data.StemSnapH.count = size; |
646 | 61.3k | } |
647 | 61.3k | } |
648 | 241k | else if (pdf_ps_name_cmp(&s->cur[-1], "StemSnapV")) { |
649 | 57.6k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY)) { |
650 | 57.6k | int i, size = s->cur[0].size > 12 ? 12 : s->cur[0].size; |
651 | | |
652 | 632k | for (i = 0; i < size; i++) { |
653 | 574k | if (pdf_ps_obj_has_type(&s->cur[0].val.arr[i], PDF_PS_OBJ_INTEGER)) { |
654 | 574k | priv->gsu.gst1.data.StemSnapV.values[i] = (float)s->cur[0].val.arr[i].val.i; |
655 | 574k | } |
656 | 64 | else if (pdf_ps_obj_has_type(&s->cur[0].val.arr[i], PDF_PS_OBJ_FLOAT)) { |
657 | 64 | priv->gsu.gst1.data.StemSnapV.values[i] = s->cur[0].val.arr[i].val.f; |
658 | 64 | } |
659 | 574k | } |
660 | 57.6k | priv->gsu.gst1.data.StemSnapV.count = size; |
661 | 57.6k | } |
662 | 57.6k | } |
663 | 183k | else if (pdf_ps_name_cmp(&s->cur[-1], "BlueScale")) { |
664 | 63.5k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) { |
665 | 0 | priv->gsu.gst1.data.BlueScale = (float)s->cur[0].val.i; |
666 | 0 | } |
667 | 63.5k | else if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_FLOAT)) { |
668 | 63.5k | priv->gsu.gst1.data.BlueScale = (float)s->cur[0].val.f; |
669 | 63.5k | } |
670 | 63.5k | } |
671 | 119k | else if (pdf_ps_name_cmp(&s->cur[-1], "Copyright")) { |
672 | 55.4k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_STRING)) { |
673 | 55.4k | pdf_string *subr_str; |
674 | | |
675 | 55.4k | code = pdfi_object_alloc(s->pdfi_ctx, PDF_STRING, (unsigned int)s->cur[0].size, (pdf_obj **)&subr_str); |
676 | 55.4k | if (code < 0) { |
677 | 0 | return code; |
678 | 0 | } |
679 | 55.4k | pdfi_countup(subr_str); |
680 | 55.4k | memcpy(subr_str->data, s->cur[0].val.name, s->cur[0].size); |
681 | | |
682 | 55.4k | pdfi_countdown(priv->u.t1.copyright); |
683 | 55.4k | priv->u.t1.copyright = subr_str; |
684 | 55.4k | } |
685 | 55.4k | } |
686 | 367k | break; |
687 | | |
688 | 367k | case 10: |
689 | 315k | if (pdf_ps_name_cmp(&s->cur[-1], "FontMatrix")) { |
690 | 65.2k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY) && s->cur[0].size >= 6 |
691 | 65.2k | && (priv->gsu.gst1.FontMatrix.xx * priv->gsu.gst1.FontMatrix.yy - priv->gsu.gst1.FontMatrix.yx * priv->gsu.gst1.FontMatrix.xy == 0)) { |
692 | 65.1k | int i; |
693 | 65.1k | double fmat[6] = { 0.001, 0, 0, 0.001, 0, 0 }; |
694 | 456k | for (i = 0; i < 6; i++) { |
695 | 390k | if (pdf_ps_obj_has_type(&s->cur[0].val.arr[i], PDF_PS_OBJ_INTEGER)) { |
696 | 40.5k | fmat[i] = (double)s->cur[0].val.arr[i].val.i; |
697 | 40.5k | } |
698 | 350k | else if (pdf_ps_obj_has_type(&s->cur[0].val.arr[i], PDF_PS_OBJ_FLOAT)) { |
699 | 350k | fmat[i] = (double)s->cur[0].val.arr[i].val.f; |
700 | 350k | } |
701 | 390k | } |
702 | 65.1k | priv->gsu.gst1.FontMatrix.xx = fmat[0]; |
703 | 65.1k | priv->gsu.gst1.FontMatrix.xy = fmat[1]; |
704 | 65.1k | priv->gsu.gst1.FontMatrix.yx = fmat[2]; |
705 | 65.1k | priv->gsu.gst1.FontMatrix.yy = fmat[3]; |
706 | 65.1k | priv->gsu.gst1.FontMatrix.tx = fmat[4]; |
707 | 65.1k | priv->gsu.gst1.FontMatrix.ty = fmat[5]; |
708 | 65.1k | priv->gsu.gst1.orig_FontMatrix = priv->gsu.gst1.FontMatrix; |
709 | 65.1k | } |
710 | 65.2k | } |
711 | 250k | else if (pdf_ps_name_cmp(&s->cur[-1], "BlueValues")) { |
712 | 61.7k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY)) { |
713 | 61.7k | int i, size = s->cur[0].size < 14 ? s->cur[0].size : 14; |
714 | | |
715 | 509k | for (i = 0; i < size; i++) { |
716 | 447k | if (pdf_ps_obj_has_type(&s->cur[0].val.arr[i], PDF_PS_OBJ_INTEGER)) { |
717 | 447k | priv->gsu.gst1.data.BlueValues.values[i] = |
718 | 447k | (float)s->cur[0].val.arr[i].val.i; |
719 | 447k | } |
720 | 0 | else if (pdf_ps_obj_has_type(&s->cur[0].val.arr[i], PDF_PS_OBJ_FLOAT)) { |
721 | 0 | priv->gsu.gst1.data.BlueValues.values[i] = s->cur[0].val.arr[i].val.f; |
722 | 0 | } |
723 | 0 | else { |
724 | 0 | if (i == 0) |
725 | 0 | priv->gsu.gst1.data.BlueValues.values[i] = 0; |
726 | 0 | else |
727 | 0 | priv->gsu.gst1.data.BlueValues.values[i] = priv->gsu.gst1.data.BlueValues.values[i - 1] + 1; |
728 | 0 | } |
729 | 447k | } |
730 | 61.7k | priv->gsu.gst1.data.BlueValues.count = size; |
731 | 61.7k | } |
732 | 61.7k | } |
733 | 188k | else if (pdf_ps_name_cmp(&s->cur[-1], "FamilyName")) { |
734 | 65.3k | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_STRING) && priv->u.t1.familyname == NULL) { |
735 | 65.3k | pdf_string *subr_str; |
736 | | |
737 | 65.3k | code = pdfi_object_alloc(s->pdfi_ctx, PDF_STRING, (unsigned int)s->cur[0].size, (pdf_obj **)&subr_str); |
738 | 65.3k | if (code < 0) { |
739 | 0 | return code; |
740 | 0 | } |
741 | 65.3k | pdfi_countup(subr_str); |
742 | 65.3k | memcpy(subr_str->data, s->cur[0].val.name, s->cur[0].size); |
743 | | |
744 | 65.3k | pdfi_countdown(priv->u.t1.familyname); |
745 | 65.3k | priv->u.t1.familyname = subr_str; |
746 | 65.3k | } |
747 | 65.3k | } |
748 | 315k | break; |
749 | | |
750 | 315k | case 11: |
751 | 65.7k | if (pdf_ps_name_cmp(&s->cur[-1], "StrokeWidth")) { |
752 | 238 | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_FLOAT)) { |
753 | 7 | priv->gsu.gst1.StrokeWidth = s->cur[0].val.f; |
754 | 7 | } |
755 | 231 | else if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER)) { |
756 | 231 | priv->gsu.gst1.StrokeWidth = (float)s->cur[0].val.i; |
757 | 231 | } |
758 | 238 | } |
759 | 65.7k | break; |
760 | 65.6k | case 12: |
761 | 65.6k | if (pdf_ps_name_cmp(&s->cur[-1], "WeightVector")) { |
762 | 0 | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY)) { |
763 | 0 | int i, size = s->cur[0].size > 16 ? 16 : s->cur[0].size; |
764 | |
|
765 | 0 | for (i = 0; i < size; i++) { |
766 | 0 | if (pdf_ps_obj_has_type(&s->cur[0].val.arr[i], PDF_PS_OBJ_INTEGER)) { |
767 | 0 | priv->gsu.gst1.data.WeightVector.values[i] = (float)s->cur[0].val.arr[i].val.i; |
768 | 0 | } |
769 | 0 | else if (pdf_ps_obj_has_type(&s->cur[0].val.arr[i], PDF_PS_OBJ_FLOAT)) { |
770 | 0 | priv->gsu.gst1.data.WeightVector.values[i] = s->cur[0].val.arr[i].val.f; |
771 | 0 | } |
772 | 0 | else { |
773 | 0 | priv->gsu.gst1.data.WeightVector.values[i] = 0; |
774 | 0 | } |
775 | 0 | } |
776 | 0 | priv->gsu.gst1.data.WeightVector.count = s->cur[0].size; |
777 | 0 | } |
778 | 0 | } |
779 | 65.6k | break; |
780 | 334 | case 14: |
781 | 334 | if (pdf_ps_name_cmp(&s->cur[-1], "BlendAxisTypes")) { |
782 | 0 | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY)) { |
783 | 0 | int i; |
784 | 0 | code = pdfi_array_alloc(s->pdfi_ctx, s->cur[0].size, &priv->u.t1.blendaxistypes); |
785 | 0 | if (code >= 0) { |
786 | 0 | pdfi_countup(priv->u.t1.blendaxistypes); |
787 | 0 | for (i = 0; i < s->cur[0].size; i++) { |
788 | 0 | pdf_ps_stack_object_t *so = &s->cur[0].val.arr[i]; |
789 | 0 | pdf_name *n; |
790 | 0 | if (pdf_ps_obj_has_type(so, PDF_PS_OBJ_NAME)) { |
791 | 0 | code = pdfi_object_alloc(s->pdfi_ctx, PDF_NAME, so->size, (pdf_obj **)&n); |
792 | 0 | if (code >= 0) { |
793 | 0 | pdfi_countup(n); |
794 | 0 | memcpy(n->data, so->val.name, so->size); |
795 | 0 | n->length = so->size; |
796 | 0 | code = pdfi_array_put(s->pdfi_ctx, priv->u.t1.blendaxistypes, i, (pdf_obj *)n); |
797 | 0 | pdfi_countdown(n); |
798 | 0 | } |
799 | 0 | } |
800 | 0 | if (code < 0) |
801 | 0 | break; |
802 | 0 | } |
803 | 0 | } |
804 | 0 | } |
805 | 0 | } |
806 | 334 | else if (pdf_ps_name_cmp(&s->cur[-1], "BlendDesignMap")) { |
807 | 0 | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY)) { |
808 | 0 | int i, j, k; |
809 | 0 | pdf_ps_stack_object_t *arr1 = &s->cur[0], *arr2, *arr3; |
810 | 0 | pdf_array *parr2, *parr3; |
811 | 0 | code = pdfi_array_alloc(s->pdfi_ctx, arr1->size, &priv->u.t1.blenddesignmap); |
812 | 0 | if (code >= 0) { |
813 | 0 | pdfi_countup(priv->u.t1.blenddesignmap); |
814 | 0 | for (i = 0; i < arr1->size && code >= 0; i++) { |
815 | 0 | if (pdf_ps_obj_has_type(&arr1->val.arr[i], PDF_PS_OBJ_ARRAY)) { |
816 | 0 | arr2 = &arr1->val.arr[i]; |
817 | 0 | code = pdfi_array_alloc(s->pdfi_ctx, arr2->size, &parr2); |
818 | 0 | if (code < 0) |
819 | 0 | break; |
820 | 0 | for (j = 0; j < arr2->size; j++) { |
821 | 0 | pdf_num *n; |
822 | |
|
823 | 0 | arr3 = &arr2->val.arr[j]; |
824 | 0 | code = pdfi_array_alloc(s->pdfi_ctx, arr3->size, &parr3); |
825 | 0 | if (code < 0) |
826 | 0 | break; |
827 | | |
828 | 0 | for (k = 0; k < arr3->size; k++) { |
829 | 0 | if (pdf_ps_obj_has_type(&arr3->val.arr[k], PDF_PS_OBJ_INTEGER)) { |
830 | 0 | code = pdfi_object_alloc(s->pdfi_ctx, PDF_INT, 0, (pdf_obj **)&n); |
831 | 0 | if (code >= 0) |
832 | 0 | n->value.i = arr3->val.arr[k].val.i; |
833 | 0 | } |
834 | 0 | else if (pdf_ps_obj_has_type(&arr1->val.arr[i], PDF_PS_OBJ_FLOAT)) { |
835 | 0 | code = pdfi_object_alloc(s->pdfi_ctx, PDF_REAL, 0, (pdf_obj **)&n); |
836 | 0 | if (code >= 0) |
837 | 0 | n->value.d = arr3->val.arr[k].val.f; |
838 | 0 | } |
839 | 0 | else { |
840 | 0 | code = pdfi_object_alloc(s->pdfi_ctx, PDF_INT, 0, (pdf_obj **)&n); |
841 | 0 | if (code >= 0) |
842 | 0 | n->value.i = 0; |
843 | 0 | } |
844 | 0 | if (code < 0) |
845 | 0 | break; |
846 | 0 | pdfi_countup(n); |
847 | 0 | code = pdfi_array_put(s->pdfi_ctx, parr3, k, (pdf_obj *)n); |
848 | 0 | pdfi_countdown(n); |
849 | 0 | if (code < 0) |
850 | 0 | break; |
851 | 0 | } |
852 | 0 | if (code < 0) |
853 | 0 | break; |
854 | 0 | pdfi_countup(parr3); |
855 | 0 | code = pdfi_array_put(s->pdfi_ctx, parr2, j, (pdf_obj *)parr3); |
856 | 0 | pdfi_countdown(parr3); |
857 | 0 | } |
858 | 0 | if (code < 0) |
859 | 0 | break; |
860 | 0 | pdfi_countup(parr2); |
861 | 0 | code = pdfi_array_put(s->pdfi_ctx, priv->u.t1.blenddesignmap, i, (pdf_obj *)parr2); |
862 | 0 | pdfi_countdown(parr2); |
863 | 0 | } |
864 | 0 | } |
865 | 0 | } |
866 | 0 | } |
867 | 0 | } |
868 | 334 | break; |
869 | | |
870 | 28 | case 20: |
871 | 28 | if (pdf_ps_name_cmp(&s->cur[-1], "BlendDesignPositions")) { |
872 | 0 | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_ARRAY)) { |
873 | 0 | code = pdfi_array_alloc(s->pdfi_ctx, s->cur[0].size, &priv->u.t1.blenddesignpositions); |
874 | 0 | if (code >= 0) { |
875 | 0 | int i, j; |
876 | 0 | pdfi_countup(priv->u.t1.blenddesignpositions); |
877 | |
|
878 | 0 | for (i = 0; i < s->cur[0].size && code >= 0; i++) { |
879 | 0 | pdf_ps_stack_object_t *so = &s->cur[0].val.arr[i]; |
880 | |
|
881 | 0 | if (pdf_ps_obj_has_type(so, PDF_PS_OBJ_ARRAY)) { |
882 | 0 | pdf_array *sa; |
883 | 0 | code = pdfi_array_alloc(s->pdfi_ctx, so->size, &sa); |
884 | 0 | if (code >= 0) { |
885 | 0 | pdfi_countup(sa); |
886 | 0 | for (j = 0; j < so->size; j++) { |
887 | 0 | pdf_num *n; |
888 | 0 | if (pdf_ps_obj_has_type(&so->val.arr[j], PDF_PS_OBJ_INTEGER)) { |
889 | 0 | code = pdfi_object_alloc(s->pdfi_ctx, PDF_INT, 0, (pdf_obj **)&n); |
890 | 0 | if (code >= 0) |
891 | 0 | n->value.i = so->val.arr[j].val.i; |
892 | 0 | } |
893 | 0 | else if (pdf_ps_obj_has_type(&so->val.arr[j], PDF_PS_OBJ_FLOAT)) { |
894 | 0 | code = pdfi_object_alloc(s->pdfi_ctx, PDF_REAL, 0, (pdf_obj **)&n); |
895 | 0 | if (code >= 0) |
896 | 0 | n->value.d = so->val.arr[j].val.f; |
897 | 0 | } |
898 | 0 | else { |
899 | 0 | code = pdfi_object_alloc(s->pdfi_ctx, PDF_INT, 0, (pdf_obj **)&n); |
900 | 0 | if (code >= 0) |
901 | 0 | n->value.i = 0; |
902 | 0 | } |
903 | 0 | if (code < 0) |
904 | 0 | break; |
905 | 0 | pdfi_countup(n); |
906 | 0 | code = pdfi_array_put(s->pdfi_ctx, sa, j, (pdf_obj *)n); |
907 | 0 | pdfi_countdown(n); |
908 | 0 | if (code < 0) break; |
909 | 0 | } |
910 | 0 | } |
911 | 0 | if (code >= 0) { |
912 | 0 | code = pdfi_array_put(s->pdfi_ctx, priv->u.t1.blenddesignpositions, i, (pdf_obj *)sa); |
913 | 0 | } |
914 | 0 | pdfi_countdown(sa); |
915 | 0 | } |
916 | 0 | } |
917 | 0 | } |
918 | |
|
919 | 0 | } |
920 | 0 | } |
921 | 28 | break; |
922 | | |
923 | 379k | default: |
924 | 379k | break; |
925 | 1.86M | } |
926 | 1.86M | } |
927 | | |
928 | 1.93M | code2 = pdf_ps_stack_pop(s, 2); |
929 | 1.93M | if (code < 0) |
930 | 34 | return code; |
931 | 1.93M | else |
932 | 1.93M | return code2; |
933 | 1.93M | } |
934 | | |
935 | | static int |
936 | | ps_font_true_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
937 | 3.23k | { |
938 | 3.23k | (void)mem; |
939 | 3.23k | return pdf_ps_stack_push_boolean(s, true); |
940 | 3.23k | } |
941 | | |
942 | | static int |
943 | | ps_font_false_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
944 | 125k | { |
945 | 125k | (void)mem; |
946 | 125k | return pdf_ps_stack_push_boolean(s, false); |
947 | 125k | } |
948 | | |
949 | | static int |
950 | | ps_font_dict_begin_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
951 | 256k | { |
952 | 256k | (void)mem; |
953 | 256k | return pdf_ps_stack_push_dict_mark(s); |
954 | 256k | } |
955 | | |
956 | | static int |
957 | | ps_font_dict_end_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
958 | 246k | { |
959 | 246k | int dsize = pdf_ps_stack_count_to_mark(s, PDF_PS_OBJ_DICT_MARK); |
960 | | |
961 | 246k | (void)mem; |
962 | 246k | if (dsize >= 0) |
963 | 180k | return pdf_ps_stack_pop(s, dsize + 1); /* Add one for the mark object */ |
964 | 65.8k | else |
965 | 65.8k | return 0; |
966 | 246k | } |
967 | | |
968 | | static stream * |
969 | | push_eexec_filter(gs_memory_t *mem, byte *buf, byte *bufend) |
970 | 64.5k | { |
971 | 64.5k | stream *fs, *ffs = NULL; |
972 | 64.5k | stream *sstrm; |
973 | 64.5k | stream_exD_state *st; |
974 | 64.5k | byte *strbuf; |
975 | | |
976 | 64.5k | sstrm = file_alloc_stream(mem, "push_eexec_filter(buf stream)"); |
977 | 64.5k | if (sstrm == NULL) |
978 | 0 | return NULL; |
979 | | |
980 | | /* Because of streams <shrug!> we advance the buffer one byte */ |
981 | 64.5k | buf++; |
982 | 64.5k | sread_string(sstrm, buf, bufend - buf); |
983 | 64.5k | sstrm->close_at_eod = false; |
984 | | |
985 | 64.5k | fs = s_alloc(mem, "push_eexec_filter(fs)"); |
986 | 64.5k | strbuf = gs_alloc_bytes(mem, 4096, "push_eexec_filter(buf)"); |
987 | 64.5k | st = gs_alloc_struct(mem, stream_exD_state, s_exD_template.stype, "push_eexec_filter(st)"); |
988 | 64.5k | if (fs == NULL || st == NULL || strbuf == NULL) { |
989 | 0 | sclose(sstrm); |
990 | 0 | gs_free_object(mem, sstrm, "push_eexec_filter(buf stream)"); |
991 | 0 | gs_free_object(mem, fs, "push_eexec_filter(fs)"); |
992 | 0 | gs_free_object(mem, st, "push_eexec_filter(st)"); |
993 | 0 | goto done; |
994 | 0 | } |
995 | 64.5k | memset(st, 0x00, sizeof(stream_exD_state)); |
996 | | |
997 | 64.5k | s_std_init(fs, strbuf, 69, &s_filter_read_procs, s_mode_read); |
998 | 64.5k | st->memory = mem; |
999 | 64.5k | st->templat = &s_exD_template; |
1000 | 64.5k | fs->state = (stream_state *) st; |
1001 | 64.5k | fs->procs.process = s_exD_template.process; |
1002 | 64.5k | fs->strm = sstrm; |
1003 | 64.5k | (*s_exD_template.set_defaults) ((stream_state *) st); |
1004 | 64.5k | st->cstate = 55665; |
1005 | 64.5k | st->binary = -1; |
1006 | 64.5k | st->lenIV = 4; |
1007 | 64.5k | st->keep_spaces = true; |
1008 | 64.5k | (*s_exD_template.init) ((stream_state *) st); |
1009 | 64.5k | fs->close_at_eod = false; |
1010 | 64.5k | ffs = fs; |
1011 | 64.5k | done: |
1012 | 64.5k | return ffs; |
1013 | 64.5k | } |
1014 | | |
1015 | | static void |
1016 | | pop_eexec_filter(gs_memory_t *mem, stream *s) |
1017 | 64.5k | { |
1018 | 64.5k | stream *src = s->strm; |
1019 | 64.5k | byte *b = s->cbuf; |
1020 | | |
1021 | 64.5k | sclose(s); |
1022 | 64.5k | gs_free_object(mem, s, "pop_eexec_filter(s)"); |
1023 | 64.5k | gs_free_object(mem, b, "pop_eexec_filter(b)"); |
1024 | 64.5k | if (src) |
1025 | 64.5k | sclose(src); |
1026 | 64.5k | gs_free_object(mem, src, "pop_eexec_filter(strm)"); |
1027 | 64.5k | } |
1028 | | |
1029 | | /* We decode the eexec data in place */ |
1030 | | static int |
1031 | | ps_font_eexec_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
1032 | 64.5k | { |
1033 | 64.5k | stream *strm; |
1034 | 64.5k | int c; |
1035 | | |
1036 | 64.5k | if (bufend <= buf) { |
1037 | 0 | return_error(gs_error_invalidfont); |
1038 | 0 | } |
1039 | | |
1040 | 64.5k | strm = push_eexec_filter(mem, buf, bufend); |
1041 | 5.48G | while (1) { |
1042 | 5.48G | c = sgetc(strm); |
1043 | 5.48G | if (c < 0) |
1044 | 64.5k | break; |
1045 | 5.48G | *buf = (byte) c; |
1046 | 5.48G | buf++; |
1047 | 5.48G | } |
1048 | 64.5k | pop_eexec_filter(mem, strm); |
1049 | | |
1050 | 64.5k | return 0; |
1051 | 64.5k | } |
1052 | | |
1053 | | /* Normally, for us, "array" is a NULL op. |
1054 | | *The exception is when the name /Subrs is two objects |
1055 | | *down from the top of the stack, then we can use this call |
1056 | | *to record how many subrs we expect, and allocate space for them |
1057 | | */ |
1058 | | static int |
1059 | | ps_font_array_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
1060 | 71.0k | { |
1061 | 71.0k | ps_font_interp_private *priv = (ps_font_interp_private *) s->client_data; |
1062 | 71.0k | int code = 0; |
1063 | | |
1064 | 71.0k | if (pdf_ps_stack_count(s) < 2) { |
1065 | 28 | return pdf_ps_stack_pop(s, 1); |
1066 | 28 | } |
1067 | 71.0k | if (pdf_ps_obj_has_type(&s->cur[-1], PDF_PS_OBJ_NAME) && |
1068 | 71.0k | pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER) && |
1069 | 71.0k | !memcmp(s->cur[-1].val.name, PDF_PS_OPER_NAME_AND_LEN("Subrs"))) { |
1070 | | |
1071 | 59.4k | if (s->cur[0].val.i > 0) { |
1072 | 59.4k | pdfi_countdown(priv->u.t1.Subrs); |
1073 | | |
1074 | 59.4k | code = pdfi_object_alloc(s->pdfi_ctx, PDF_ARRAY, (unsigned int)s->cur[0].val.i, (pdf_obj **)&priv->u.t1.Subrs); |
1075 | 59.4k | if (code < 0) { |
1076 | 0 | return code; |
1077 | 0 | } |
1078 | 59.4k | pdfi_countup(priv->u.t1.Subrs); |
1079 | 59.4k | } |
1080 | 59.4k | code = pdf_ps_stack_pop(s, 1); |
1081 | 59.4k | } |
1082 | 11.5k | else if (pdf_ps_obj_has_type(&s->cur[-1], PDF_PS_OBJ_NAME) && |
1083 | 11.5k | pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER) && |
1084 | 11.5k | !memcmp(s->cur[-1].val.name, PDF_PS_OPER_NAME_AND_LEN("Encoding"))) { |
1085 | | /* We're defining a custom encoding array */ |
1086 | 11.1k | pdf_ps_stack_object_t *arr = NULL; |
1087 | 11.1k | int size = s->cur[0].val.i; |
1088 | | |
1089 | 11.1k | if (size > 0) { |
1090 | 11.1k | arr = (pdf_ps_stack_object_t *) gs_alloc_bytes(mem, size *sizeof(pdf_ps_stack_object_t), "ps_font_array_func(encoding array)"); |
1091 | 11.1k | if (arr != NULL) { |
1092 | 11.1k | code = pdf_ps_stack_pop(s, 1); |
1093 | 11.1k | if (code < 0) { |
1094 | 0 | gs_free_object(mem, arr, "ps_font_array_func(encoding array)"); |
1095 | 0 | } |
1096 | 11.1k | else { |
1097 | 11.1k | int i; |
1098 | | |
1099 | 2.85M | for (i = 0; i < size; i++) { |
1100 | 2.84M | pdf_ps_make_name(&arr[i], (byte *) notdefnamestr, strlen(notdefnamestr)); |
1101 | 2.84M | } |
1102 | 11.1k | code = pdf_ps_stack_push_array(s, arr, size); |
1103 | 11.1k | } |
1104 | 11.1k | } |
1105 | 0 | else { |
1106 | 0 | code = gs_note_error(gs_error_VMerror); |
1107 | 0 | } |
1108 | 11.1k | } |
1109 | 11.1k | } |
1110 | 71.0k | return code; |
1111 | 71.0k | } |
1112 | | |
1113 | | /* Normally, for us, "dict" is a NULL op. |
1114 | | *The exception is when the name /CharStrings is two objects |
1115 | | *down from the top of the stack, then we can use this call |
1116 | | *to record how many charstrings we expect, and allocate space for them |
1117 | | */ |
1118 | | static int |
1119 | | ps_font_dict_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
1120 | 256k | { |
1121 | 256k | ps_font_interp_private *priv = (ps_font_interp_private *) s->client_data; |
1122 | | |
1123 | 256k | if (pdf_ps_stack_count(s) < 2) { |
1124 | 65.9k | return pdf_ps_stack_pop(s, 1); |
1125 | 65.9k | } |
1126 | 190k | if (pdf_ps_obj_has_type(&s->cur[-1], PDF_PS_OBJ_NAME) && |
1127 | 190k | pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER) && |
1128 | 190k | !memcmp(s->cur[-1].val.name, PDF_PS_OPER_NAME_AND_LEN("CharStrings"))) { |
1129 | 60.2k | int code; |
1130 | 60.2k | pdf_dict *d = NULL; |
1131 | | |
1132 | 60.2k | if (priv->u.t1.CharStrings == NULL) { |
1133 | 60.2k | code = pdfi_dict_alloc(s->pdfi_ctx, s->cur[0].val.i, &d); |
1134 | 60.2k | if (code < 0) { |
1135 | 0 | priv->u.t1.CharStrings = NULL; |
1136 | 0 | (void)pdf_ps_stack_pop(s, 1); |
1137 | 0 | return code; |
1138 | 0 | } |
1139 | | |
1140 | 60.2k | priv->u.t1.CharStrings = d; |
1141 | 60.2k | pdfi_countup(priv->u.t1.CharStrings); |
1142 | 60.2k | } |
1143 | 60.2k | } |
1144 | 190k | return pdf_ps_stack_pop(s, 1); |
1145 | 190k | } |
1146 | | |
1147 | | static int |
1148 | | pdf_ps_pop2_oper_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
1149 | 105k | { |
1150 | 105k | return pdf_ps_stack_pop(s, 2); |
1151 | 105k | } |
1152 | | |
1153 | | static int |
1154 | | pdf_ps_pop4_oper_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
1155 | 11.1k | { |
1156 | 11.1k | return pdf_ps_stack_pop(s, 4); |
1157 | 11.1k | } |
1158 | | |
1159 | | static int |
1160 | | pdf_ps_standardencoding_oper_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
1161 | 56.0k | { |
1162 | 56.0k | return pdf_ps_stack_push_name(s, (byte *) "StandardEncoding", 16); |
1163 | 56.0k | } |
1164 | | |
1165 | | /* { string currentfile exch readstring pop } */ |
1166 | | static int |
1167 | | pdf_ps_RD_oper_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
1168 | 43.1M | { |
1169 | 43.1M | ps_font_interp_private *priv = (ps_font_interp_private *) s->client_data; |
1170 | 43.1M | int code; |
1171 | 43.1M | int size = 0; |
1172 | | |
1173 | 43.1M | if (pdf_ps_stack_count(s) >= 1) { |
1174 | 43.1M | if (priv->u.t1.Subrs != NULL && priv->u.t1.CharStrings == NULL) { |
1175 | 1.16M | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER) && |
1176 | 1.16M | pdf_ps_obj_has_type(&s->cur[-1], PDF_PS_OBJ_INTEGER)) { |
1177 | 1.16M | int inx = s->cur[-1].val.i; |
1178 | | |
1179 | 1.16M | size = s->cur[0].val.i; |
1180 | 1.16M | if (size < 0) |
1181 | 0 | return_error(gs_error_invalidfont); |
1182 | | |
1183 | 1.16M | buf++; |
1184 | 1.16M | if (buf + size < bufend) { |
1185 | 1.16M | pdf_string *subr_str; |
1186 | | |
1187 | 1.16M | code = pdfi_object_alloc(s->pdfi_ctx, PDF_STRING, (unsigned int)size, (pdf_obj **)&subr_str); |
1188 | 1.16M | if (code < 0) { |
1189 | 0 | return code; |
1190 | 0 | } |
1191 | 1.16M | memcpy(subr_str->data, buf, size); |
1192 | 1.16M | pdfi_countup(subr_str); |
1193 | 1.16M | code = pdfi_array_put(s->pdfi_ctx, priv->u.t1.Subrs, inx, (pdf_obj *)subr_str); |
1194 | 1.16M | pdfi_countdown(subr_str); |
1195 | 1.16M | if (code < 0) |
1196 | 0 | return code; |
1197 | 1.16M | } |
1198 | 1.16M | } |
1199 | 1.16M | } |
1200 | 42.0M | else if (priv->u.t1.CharStrings != NULL) { |
1201 | 42.0M | if (pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_INTEGER) && |
1202 | 42.0M | pdf_ps_obj_has_type(&s->cur[-1], PDF_PS_OBJ_NAME)) { |
1203 | 42.0M | pdf_string *str = NULL; |
1204 | 42.0M | pdf_obj *key = NULL; |
1205 | | |
1206 | 42.0M | size = s->cur[0].val.i; |
1207 | 42.0M | if (size < 0) |
1208 | 0 | return_error(gs_error_invalidfont); |
1209 | | |
1210 | 42.0M | buf++; |
1211 | 42.0M | code = pdfi_name_alloc(s->pdfi_ctx, (byte *) s->cur[-1].val.name, s->cur[-1].size, &key); |
1212 | 42.0M | if (code < 0) { |
1213 | 0 | (void)pdf_ps_stack_pop(s, 2); |
1214 | 0 | return code; |
1215 | 0 | } |
1216 | 42.0M | pdfi_countup(key); |
1217 | | |
1218 | 42.0M | if (buf + size < bufend) { |
1219 | 42.0M | code = pdfi_object_alloc(s->pdfi_ctx, PDF_STRING, size, (pdf_obj **) &str); |
1220 | 42.0M | if (code < 0) { |
1221 | 0 | pdfi_countdown(key); |
1222 | 0 | (void)pdf_ps_stack_pop(s, 2); |
1223 | 0 | return code; |
1224 | 0 | } |
1225 | 42.0M | pdfi_countup(str); |
1226 | 42.0M | memcpy(str->data, buf, size); |
1227 | | |
1228 | 42.0M | code = pdfi_dict_put_obj(s->pdfi_ctx, priv->u.t1.CharStrings, key, (pdf_obj *) str, false); |
1229 | 42.0M | if (code < 0) { |
1230 | 0 | pdfi_countdown(str); |
1231 | 0 | pdfi_countdown(key); |
1232 | 0 | (void)pdf_ps_stack_pop(s, 2); |
1233 | 0 | return code; |
1234 | 0 | } |
1235 | 42.0M | } |
1236 | 42.0M | pdfi_countdown(str); |
1237 | 42.0M | pdfi_countdown(key); |
1238 | 42.0M | } |
1239 | 42.0M | } |
1240 | 43.1M | code = pdf_ps_stack_pop(s, 2); |
1241 | 43.1M | return code < 0 ? code : size + 1; |
1242 | 43.1M | } |
1243 | 0 | return 0; |
1244 | 43.1M | } |
1245 | | |
1246 | | static int |
1247 | | pdf_ps_put_oper_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
1248 | 693k | { |
1249 | 693k | int code; |
1250 | | |
1251 | 693k | if ((code = pdf_ps_stack_count(s)) < 4) { |
1252 | 184k | return 0; |
1253 | 184k | } |
1254 | | |
1255 | 509k | if (pdf_ps_obj_has_type(&s->cur[-3], PDF_PS_OBJ_NAME) && |
1256 | 509k | !memcmp(s->cur[-3].val.name, PDF_PS_OPER_NAME_AND_LEN("Encoding")) && |
1257 | 509k | pdf_ps_obj_has_type(&s->cur[-2], PDF_PS_OBJ_ARRAY) && |
1258 | 509k | pdf_ps_obj_has_type(&s->cur[-1], PDF_PS_OBJ_INTEGER) && |
1259 | 509k | pdf_ps_obj_has_type(&s->cur[0], PDF_PS_OBJ_NAME)) { |
1260 | 486k | if (s->cur[-1].val.i >= 0 && s->cur[-1].val.i < s->cur[-2].size) { |
1261 | 485k | pdf_ps_make_name(&s->cur[-2].val.arr[s->cur[-1].val.i], s->cur[0].val.name, s->cur[0].size); |
1262 | 485k | } |
1263 | 486k | } |
1264 | | |
1265 | 509k | code = pdf_ps_stack_pop(s, 2); |
1266 | 509k | return code; |
1267 | 693k | } |
1268 | | |
1269 | | static int |
1270 | | pdf_ps_closefile_oper_func(gs_memory_t *mem, pdf_ps_ctx_t *s, byte *buf, byte *bufend) |
1271 | 57.7k | { |
1272 | 57.7k | return bufend - buf; |
1273 | 57.7k | } |
1274 | | |
1275 | | static pdf_ps_oper_list_t ps_font_oper_list[] = { |
1276 | | {PDF_PS_OPER_NAME_AND_LEN("RD"), pdf_ps_RD_oper_func}, |
1277 | | {PDF_PS_OPER_NAME_AND_LEN("-|"), pdf_ps_RD_oper_func}, |
1278 | | {PDF_PS_OPER_NAME_AND_LEN("|"), pdf_ps_put_oper_func}, |
1279 | | {PDF_PS_OPER_NAME_AND_LEN("findresource"), clear_stack_oper_func}, |
1280 | | {PDF_PS_OPER_NAME_AND_LEN("dict"), ps_font_dict_func}, |
1281 | | {PDF_PS_OPER_NAME_AND_LEN("begin"), ps_font_dict_begin_func}, |
1282 | | {PDF_PS_OPER_NAME_AND_LEN("end"), ps_font_dict_end_func}, |
1283 | | {PDF_PS_OPER_NAME_AND_LEN("pop"), ps_pdf_null_oper_func}, |
1284 | | {PDF_PS_OPER_NAME_AND_LEN("def"), ps_font_def_func}, |
1285 | | {PDF_PS_OPER_NAME_AND_LEN("dup"), ps_pdf_null_oper_func}, |
1286 | | {PDF_PS_OPER_NAME_AND_LEN("defineresource"), clear_stack_oper_func}, |
1287 | | {PDF_PS_OPER_NAME_AND_LEN("definefont"), clear_stack_oper_func}, |
1288 | | {PDF_PS_OPER_NAME_AND_LEN("readonly"), ps_pdf_null_oper_func}, |
1289 | | {PDF_PS_OPER_NAME_AND_LEN("true"), ps_font_true_func}, |
1290 | | {PDF_PS_OPER_NAME_AND_LEN("false"), ps_font_false_func}, |
1291 | | {PDF_PS_OPER_NAME_AND_LEN("eexec"), ps_font_eexec_func}, |
1292 | | {PDF_PS_OPER_NAME_AND_LEN("array"), ps_font_array_func}, |
1293 | | {PDF_PS_OPER_NAME_AND_LEN("known"), pdf_ps_pop_oper_func}, |
1294 | | {PDF_PS_OPER_NAME_AND_LEN("if"), pdf_ps_pop_oper_func}, |
1295 | | {PDF_PS_OPER_NAME_AND_LEN("ifelse"), pdf_ps_pop2_oper_func}, |
1296 | | {PDF_PS_OPER_NAME_AND_LEN("for"), pdf_ps_pop4_oper_func}, |
1297 | | {PDF_PS_OPER_NAME_AND_LEN("put"), pdf_ps_put_oper_func}, |
1298 | | {PDF_PS_OPER_NAME_AND_LEN("StandardEncoding"), pdf_ps_standardencoding_oper_func}, |
1299 | | {PDF_PS_OPER_NAME_AND_LEN("closefile"), pdf_ps_closefile_oper_func}, |
1300 | | {NULL, 0, NULL} |
1301 | | }; |
1302 | | |
1303 | | int |
1304 | | pdfi_read_ps_font(pdf_context *ctx, pdf_dict *font_dict, byte *fbuf, int fbuflen, ps_font_interp_private *ps_font_priv) |
1305 | 66.5k | { |
1306 | 66.5k | int code = 0; |
1307 | 66.5k | pdf_ps_ctx_t ps_font_ctx; |
1308 | | |
1309 | 66.5k | code = pdfi_pscript_stack_init(ctx, ps_font_oper_list, ps_font_priv, &ps_font_ctx); |
1310 | 66.5k | if (code < 0) |
1311 | 0 | goto error_out; |
1312 | | |
1313 | 66.5k | code = pdfi_pscript_interpret(&ps_font_ctx, fbuf, fbuflen); |
1314 | 66.5k | pdfi_pscript_stack_finit(&ps_font_ctx); |
1315 | | /* We have several files that have a load of garbage data in the stream after the font is defined, |
1316 | | and that can end up in a stackoverflow error, even though we have a complete font. Override it |
1317 | | and let the Type 1 specific code decide for itself if it can use the font. |
1318 | | */ |
1319 | 66.5k | if (code == gs_error_pdf_stackoverflow) |
1320 | 0 | code = 0; |
1321 | | |
1322 | 66.5k | return code; |
1323 | 0 | error_out: |
1324 | 0 | code = gs_error_invalidfont; |
1325 | 0 | return code; |
1326 | 66.5k | } |