1 /*---------------------------------------------------------------------------*
2 | PDFlib - A library for generating PDF on the fly |
3 +---------------------------------------------------------------------------+
4 | Copyright (c) 1997-2006 Thomas Merz and PDFlib GmbH. All rights reserved. |
5 +---------------------------------------------------------------------------+
6 | |
7 | This software is subject to the PDFlib license. It is NOT in the |
8 | public domain. Extended versions and commercial licenses are |
9 | available, please check http://www.pdflib.com. |
10 | |
11 *---------------------------------------------------------------------------*/
12
13 /* $Id: p_util.c,v 1.169.2.34 2009/10/09 09:35:27 kurt Exp $
14 *
15 * PDFlib utility functions
16 *
17 */
18
19 #define P_UTIL_C
20
21 #include "p_intern.h"
22 #include "p_font.h"
23 #include "p_image.h"
24 #include "p_layer.h"
25
26
27 /* ------------------------- [hyper]textformat -----------------------------*/
28
29 void
pdf_check_textformat(PDF * p,pdc_text_format textformat)30 pdf_check_textformat(PDF *p, pdc_text_format textformat)
31 {
32 if (!p->pdc->ptfrun && p->pdc->unicaplang && textformat != pdc_auto2)
33 pdc_error(p->pdc, PDF_E_ENC_UNSUPPENCFORMAT, "textformat", 0, 0, 0);
34
35 pdc_logg_cond(p->pdc, 1, trc_encoding, "\tTextformat: \"%s\"\n",
36 pdc_get_keyword(textformat, pdf_textformat_keylist));
37 }
38
39 void
pdf_check_hypertextformat(PDF * p,pdc_text_format hypertextformat)40 pdf_check_hypertextformat(PDF *p, pdc_text_format hypertextformat)
41 {
42 if (!p->pdc->ptfrun && p->pdc->unicaplang && hypertextformat != pdc_auto2)
43 pdc_error(p->pdc, PDF_E_ENC_UNSUPPENCFORMAT, "hypertextformat",
44 0, 0, 0);
45
46 pdc_logg_cond(p->pdc, 1, trc_encoding, "\tHypertextformat: \"%s\"\n",
47 pdc_get_keyword(hypertextformat, pdf_textformat_keylist));
48 }
49
50
51 /* ------------------------- hypertextencoding -----------------------------*/
52
53 void
pdf_check_hypertextencoding(PDF * p,pdc_encoding hypertextencoding)54 pdf_check_hypertextencoding(PDF *p, pdc_encoding hypertextencoding)
55 {
56 if (!p->pdc->ptfrun && p->pdc->unicaplang &&
57 hypertextencoding != pdc_unicode)
58 pdc_error(p->pdc, PDF_E_ENC_UNSUPPENCFORMAT, "hypertextencoding",
59 0, 0, 0);
60
61 pdc_logg_cond(p->pdc, 1, trc_encoding, "\tHypertextencoding: \"%s\"\n",
62 pdc_get_user_encoding(p->pdc, hypertextencoding));
63 }
64
65
66 /* ----------------------- string utility functions -----------------------*/
67
68 static void
pdf_set_convertflags(PDF * p,int * convflags)69 pdf_set_convertflags(PDF *p, int *convflags)
70 {
71 (void) p;
72 (void) convflags;
73
74 }
75
76 const char *
pdf__utf16_to_utf8(PDF * p,const char * utf16string,int len,int * size)77 pdf__utf16_to_utf8(PDF *p, const char *utf16string, int len, int *size)
78 {
79 char *utf8string;
80 int convflags = PDC_CONV_WITHBOM | PDC_CONV_EBCDIC | PDC_CONV_TRY7BYTES;
81
82 pdf_set_convertflags(p, &convflags);
83 utf8string = pdc_utf16_to_utf8(p->pdc, utf16string, len, convflags, size);
84
85 pdf_insert_utilstring(p, utf8string, pdc_false);
86
87 return utf8string;
88 }
89
90 const char *
pdf__utf32_to_utf16(PDF * p,const char * utf32string,int len,const char * ordering,int * outlen)91 pdf__utf32_to_utf16(PDF *p, const char *utf32string, int len,
92 const char *ordering, int *outlen)
93 {
94 char *utf16string = pdc_utf32_to_utf16(p->pdc, utf32string, len,
95 ordering, 0, outlen);
96
97 pdf_insert_utilstring(p, utf16string, pdc_false);
98
99 return utf16string;
100 }
101
102 const char *
pdf__utf8_to_utf16(PDF * p,const char * utf8string,const char * ordering,int * outlen)103 pdf__utf8_to_utf16(PDF *p, const char *utf8string, const char *ordering,
104 int *outlen)
105 {
106 char *utf16string;
107 int convflags = PDC_CONV_EBCDIC;
108
109 pdf_set_convertflags(p, &convflags);
110 utf16string = pdc_utf8_to_utf16(p->pdc, utf8string, ordering,
111 convflags, outlen);
112
113 pdf_insert_utilstring(p, utf16string, pdc_false);
114
115 return utf16string;
116 }
117
118 void
pdf_init_stringlists(PDF * p)119 pdf_init_stringlists(PDF *p)
120 {
121 p->stringlists_number = 0;
122 p->stringlists_capacity = 0;
123 p->stringlists = NULL;
124 p->stringlistsizes = NULL;
125 p->utilstrlist_index = -1;
126 p->utilstring_number = 0;
127 }
128
129 int
pdf_insert_stringlist(PDF * p,char ** stringlist,int ns)130 pdf_insert_stringlist(PDF *p, char **stringlist, int ns)
131 {
132 static const char fn[] = "pdf_insert_stringlist";
133 int i;
134
135 if (p->stringlists_number == p->stringlists_capacity)
136 {
137 int j = p->stringlists_capacity;
138
139 if (!p->stringlists_capacity)
140 {
141 p->stringlists_capacity = STRINGLISTS_CHUNKSIZE;
142
143 p->stringlists = (char ***) pdc_malloc(p->pdc,
144 sizeof(char **) * p->stringlists_capacity, fn);
145
146 p->stringlistsizes = (int *) pdc_malloc(p->pdc,
147 sizeof(int) * p->stringlists_capacity, fn);
148 }
149 else
150 {
151 p->stringlists_capacity *= 2;
152 p->stringlists = (char ***) pdc_realloc(p->pdc, p->stringlists,
153 sizeof(char **) * p->stringlists_capacity, fn);
154
155 p->stringlistsizes = (int *) pdc_realloc(p->pdc, p->stringlistsizes,
156 sizeof(int) * p->stringlists_capacity, fn);
157 }
158 for (i = j; i < p->stringlists_capacity; i++)
159 {
160 p->stringlists[i] = NULL;
161 p->stringlistsizes[i] = 0;
162 }
163 }
164
165 i = p->stringlists_number;
166 p->stringlists[i] = stringlist;
167 p->stringlistsizes[i] = ns;
168 p->stringlists_number++;
169
170 return i;
171 }
172
173 void
pdf_cleanup_stringlists(PDF * p)174 pdf_cleanup_stringlists(PDF *p)
175 {
176 int i;
177
178 if (p->stringlists)
179 {
180 for (i = 0; i < p->stringlists_number; i++)
181 {
182 if (p->stringlists[i])
183 pdc_cleanup_optstringlist(p->pdc,
184 p->stringlists[i], p->stringlistsizes[i]);
185 }
186 pdc_free(p->pdc, p->stringlists);
187 pdc_free(p->pdc, p->stringlistsizes);
188 }
189
190 pdf_init_stringlists(p);
191 }
192
193 #define PDF_MAX_UTILSTRLISTS 10
194
195 int
pdf_insert_utilstring(PDF * p,const char * utilstring,pdc_bool kdup)196 pdf_insert_utilstring(PDF *p, const char *utilstring, pdc_bool kdup)
197 {
198 static const char fn[] = "pdf_insert_utilstring";
199 char **utilstrlist;
200 int i = 0;
201
202 if (p->utilstrlist_index == -1)
203 {
204 utilstrlist = (char **) pdc_calloc(p->pdc,
205 PDF_MAX_UTILSTRLISTS * sizeof (char *), fn);
206 p->utilstrlist_index =
207 pdf_insert_stringlist(p, utilstrlist, PDF_MAX_UTILSTRLISTS);
208 }
209 utilstrlist = p->stringlists[p->utilstrlist_index];
210
211 if (p->utilstring_number >= PDF_MAX_UTILSTRLISTS)
212 p->utilstring_number = 0;
213 i = p->utilstring_number;
214 if (utilstrlist[i] != NULL)
215 pdc_free(p->pdc, utilstrlist[i]);
216 if (kdup)
217 utilstrlist[i] = pdc_strdup_ext(p->pdc, utilstring, 0, fn);
218 else
219 utilstrlist[i] = (char *) utilstring;
220 p->utilstring_number++;
221
222 return i;
223 }
224
225 const char *
pdf_get_utilstring(PDF * p,int i)226 pdf_get_utilstring(PDF *p, int i)
227 {
228 if (p->utilstrlist_index > -1 && i > -1 && i < p->utilstring_number)
229 {
230 char **utilstrlist = p->stringlists[p->utilstrlist_index];
231 return utilstrlist[i];
232 }
233
234 return NULL;
235 }
236
237 /* ------------------------ name treatment -------------------------------*/
238
239 void
pdf_put_pdfname(PDF * p,const char * name)240 pdf_put_pdfname(PDF *p, const char *name)
241 {
242 char *ascname = (char *) name;
243 int len = (int) strlen(ascname);
244
245
246 pdc_put_pdfname(p->out, ascname, len);
247
248 }
249
250
251 /* ---------------------- hyper text treatment -------------------------------*/
252
253 pdc_encoding
pdf_get_hypertextencoding_opt(PDF * p,pdc_resopt * resopts,int * codepage,pdc_bool verbose)254 pdf_get_hypertextencoding_opt(PDF *p, pdc_resopt *resopts, int *codepage,
255 pdc_bool verbose)
256 {
257 char **strlist;
258 pdc_encoding htenc;
259
260 if (pdc_get_optvalues("hypertextencoding", resopts, NULL, &strlist))
261 {
262 int cp;
263
264 htenc = pdf_get_hypertextencoding(p, strlist[0], &cp, verbose);
265 pdf_check_hypertextencoding(p, htenc);
266
267 if (codepage)
268 *codepage = cp;
269 }
270 else
271 {
272 htenc = pdf_get_hypertextencoding_param(p, codepage);
273 }
274
275 return htenc;
276 }
277
278 /* hypertext conversion for deprecated functions */
279 char *
pdf_convert_hypertext_depr(PDF * p,const char * text,int len)280 pdf_convert_hypertext_depr(PDF *p, const char *text, int len)
281 {
282 int outlen;
283
284 pdf_get_hypertextencoding_param(p, NULL);
285
286 return pdf_convert_hypertext(p, text, len, p->hypertextformat,
287 p->hypertextencoding, p->hypertextcodepage, &outlen,
288 PDC_UTF8_FLAG, pdc_true);
289 }
290
291 /*
292 * Conversion to PDFDoc/EBCDIC or UTF-16/[EBCDIC-]UTF-8
293 */
294 char *
pdf_convert_hypertext(PDF * p,const char * text,int len,pdc_text_format hypertextformat,pdc_encoding hypertextencoding,int codepage,int * outlen,pdc_bool oututf8,pdc_bool verbose)295 pdf_convert_hypertext(PDF *p, const char *text, int len,
296 pdc_text_format hypertextformat, pdc_encoding hypertextencoding,
297 int codepage, int *outlen, pdc_bool oututf8, pdc_bool verbose)
298 {
299 pdc_encodingvector *inev = NULL, *outev = NULL;
300 pdc_byte *intext = (pdc_byte *) text, *outtext = NULL;
301 pdc_text_format textformat = pdc_utf16be;
302 int convflags = PDC_CONV_WITHBOM | PDC_CONV_TRYBYTES;
303
304 *outlen = 0;
305
306 if (text == NULL)
307 return NULL;
308
309 if (len == 0)
310 len = (int) strlen(text);
311
312 /* incoming encoding */
313 if (hypertextencoding >= 0)
314 {
315 inev = pdc_get_encoding_vector(p->pdc, hypertextencoding);
316 }
317
318 /* PDFDocEncoding */
319 outev = pdc_get_encoding_vector(p->pdc, pdc_pdfdoc);
320
321 /* conversion to UTF-16-BE or PDFDocEncoding / EBCDIC */
322 pdf_set_convertflags(p, &convflags);
323 if (pdc_logg_is_enabled(p->pdc, 3, trc_text))
324 convflags |= PDC_CONV_LOGGING;
325
326 pdc_convert_string(p->pdc, hypertextformat, codepage, inev,
327 intext, len,
328 &textformat, outev, &outtext, outlen,
329 convflags, verbose);
330
331
332 /* conversion to UTF-8 if Unicode */
333 if (oututf8 && textformat == pdc_utf16be)
334 {
335 pdc_text_format outtextformat = PDC_UTF8;
336 pdc_byte *newtext = NULL;
337
338 convflags = PDC_CONV_WITHBOM;
339 if (pdc_logg_is_enabled(p->pdc, 3, trc_text))
340 convflags |= PDC_CONV_LOGGING;
341
342 pdc_convert_string(p->pdc, textformat, 0, NULL, outtext, *outlen,
343 &outtextformat, NULL, &newtext, outlen,
344 convflags, verbose);
345 pdc_free(p->pdc, outtext);
346 outtext = newtext;
347 }
348
349 return (char *) outtext;
350 }
351
352
353 /*
354 * Conversion from [EBCDIC-]UTF-8 to UTF-16 and from EBCDIC to PDFDoc
355 */
356
357 char *
pdf_convert_pdfstring(PDF * p,const char * text,int inlen,int convflags,int * outlen)358 pdf_convert_pdfstring(PDF *p, const char *text, int inlen, int convflags,
359 int *outlen)
360 {
361 pdc_byte *newtext = NULL;
362
363 if (pdc_is_utf8_bytecode(text))
364 {
365 pdc_text_format textformat = PDC_UTF8;
366 pdc_text_format outtextformat = pdc_utf16be;
367 pdc_encodingvector *outev = pdc_get_encoding_vector(p->pdc, pdc_pdfdoc);
368
369 pdf_set_convertflags(p, &convflags);
370
371 pdc_convert_string(p->pdc, textformat, 0, NULL,
372 (pdc_byte *) text, inlen,
373 &outtextformat, outev, &newtext, outlen,
374 convflags, pdc_true);
375 }
376 else
377 {
378 newtext = (pdc_byte *) text;
379 *outlen = inlen;
380 }
381
382 return (char *) newtext;
383 }
384
385 void
pdf_put_hypertext(PDF * p,const char * text)386 pdf_put_hypertext(PDF *p, const char *text)
387 {
388 int convflags = PDC_CONV_WITHBOM | PDC_CONV_TRYBYTES;
389 int inlen = (int) pdc_strlen(text);
390 int outlen;
391
392 char *newtext = pdf_convert_pdfstring(p, text, inlen, convflags, &outlen);
393
394 pdc_put_pdfstring(p->out, newtext, outlen);
395
396 if (newtext != text)
397 pdc_free(p->pdc, newtext);
398 }
399
400 void
pdf_put_pdffilename(PDF * p,const char * text)401 pdf_put_pdffilename(PDF *p, const char *text)
402 {
403 int convflags = PDC_CONV_FILENAME | PDC_CONV_TRYBYTES;
404 int inlen = (int) pdc_strlen(text);
405 int outlen;
406
407 char *newtext = pdf_convert_pdfstring(p, text, inlen, convflags, &outlen);
408
409 pdc_put_pdffilename(p->out, newtext, outlen);
410
411 if (newtext != text)
412 pdc_free(p->pdc, newtext);
413 }
414
415 void
pdf_put_pdfunifilename(PDF * p,const char * text)416 pdf_put_pdfunifilename(PDF *p, const char *text)
417 {
418 int convflags = PDC_CONV_WITHBOM | PDC_CONV_TRYBYTES;
419 int inlen = (int) pdc_strlen(text);
420 int outlen;
421
422 char *newtext = pdf_convert_pdfstring(p, text, inlen, convflags, &outlen);
423
424 pdc_put_pdffilename(p->out, newtext, outlen);
425
426 if (newtext != text)
427 pdc_free(p->pdc, newtext);
428 }
429
430
431 /* ------------------------ name strings -------------------------------*/
432
433 static void
pdf_prepare_name_string(PDF * p,const char * name,int len,int maxlen,char ** newname,int * newlen,pdc_encoding * htenc,int * htcp)434 pdf_prepare_name_string(PDF *p, const char *name, int len, int maxlen,
435 char **newname, int *newlen,
436 pdc_encoding *htenc, int *htcp)
437 {
438 if (name == NULL)
439 {
440 len = 0;
441 name = "";
442 }
443
444 if (len < 0 || len > maxlen)
445 {
446 pdc_error(p->pdc, PDC_E_ILLARG_STRINGLEN,
447 pdc_errprintf(p->pdc, "%d", len),
448 pdc_errprintf(p->pdc, "%d", PDC_SHRT_MAX), 0, 0);
449 }
450
451 *newname = (char *) name;
452 *newlen = len;
453 *htenc = pdc_invalidenc;
454 *htcp = 0;
455
456 if (p->usehyptxtenc && !len && !pdc_is_utf8_bytecode(name))
457 {
458 *htenc = pdf_get_hypertextencoding_param(p, htcp);
459
460 }
461 }
462
463 char *
pdf_convert_name(PDF * p,const char * name,int len,int flags)464 pdf_convert_name(PDF *p, const char *name, int len, int flags)
465 {
466 char *resname;
467 char *newname;
468 int newlen;
469 pdc_encoding htenc;
470 int htcp;
471
472 pdf_prepare_name_string(p, name, len, PDC_SHRT_MAX,
473 &newname, &newlen, &htenc, &htcp);
474
475 flags |= PDC_CONV_EBCDIC;
476 if (pdc_logg_is_enabled(p->pdc, 3, trc_text))
477 flags |= PDC_CONV_LOGGING;
478
479 resname = pdc_convert_name_ext(p->pdc, newname, newlen, htenc, htcp, flags);
480 if (newname != name)
481 pdc_free(p->pdc, newname);
482
483 return resname;
484 }
485
486 const char *
pdf_convert_filename(PDF * p,const char * filename,int len,const char * paramname,int flags)487 pdf_convert_filename(PDF *p, const char *filename, int len,
488 const char *paramname, int flags)
489 {
490 const char *resfilename;
491 char *newfilename;
492 int newlen;
493 pdc_encoding htenc;
494 int htcp;
495
496 pdf_prepare_name_string(p, filename, len, PDC_FILENAMELEN - 1,
497 &newfilename, &newlen, &htenc, &htcp);
498
499 flags |= PDC_CONV_EBCDIC;
500 if (pdc_logg_is_enabled(p->pdc, 3, trc_filesearch))
501 flags |= PDC_CONV_LOGGING;
502
503 resfilename = pdc_convert_filename_ext(p->pdc, newfilename, len,
504 paramname, htenc, htcp, flags);
505 if (newfilename != filename)
506 pdc_free(p->pdc, newfilename);
507
508 return resfilename;
509 }
510
511 void
pdf_add_pdflib_resource(PDF * p,const char * category,const char * resname)512 pdf_add_pdflib_resource(PDF *p, const char *category, const char *resname)
513 {
514 char *newresname;
515 int newlen;
516 pdc_encoding htenc;
517 int htcp;
518
519 pdf_prepare_name_string(p, resname, 0, PDC_FILENAMELEN,
520 &newresname, &newlen, &htenc, &htcp);
521 if (newlen)
522 {
523 char *tmpresname = pdc_utf16_to_utf8(p->pdc, newresname, newlen,
524 PDC_CONV_EBCDIC | PDC_CONV_WITHBOM,
525 &newlen);
526 pdc_free(p->pdc, newresname);
527 newresname = tmpresname;
528 newlen = 0;
529 }
530
531 pdc_add_resource_ext(p->pdc, category, newresname, NULL, htenc, htcp);
532
533 if (newresname != resname)
534 pdc_free(p->pdc, newresname);
535 }
536
537 /* ------------------------ option text list -------------------------------*/
538
539 int
pdf_get_opt_textlist(PDF * p,const char * keyword,pdc_resopt * resopts,pdc_encoding enc,int codepage,pdc_bool ishypertext,const char * fieldname,char ** text,char *** textlist)540 pdf_get_opt_textlist(PDF *p, const char *keyword, pdc_resopt *resopts,
541 pdc_encoding enc, int codepage, pdc_bool ishypertext,
542 const char *fieldname, char **text, char ***textlist)
543 {
544 pdc_bool logg1 = pdc_logg_is_enabled(p->pdc, 1, trc_optlist);
545 int ns;
546 char **strlist;
547
548 ns = pdc_get_optvalues(keyword, resopts, NULL, &strlist);
549 if (ns)
550 {
551 pdc_byte *string = NULL;
552 pdc_encodingvector *inev = NULL, *outev = NULL;
553 pdc_text_format intextformat = pdc_bytes;
554 pdc_text_format outtextformat = pdc_utf16be;
555 pdc_text_format textformat;
556 int convflags = PDC_CONV_WITHBOM;
557 pdc_bool isutf8;
558 int i, outlen;
559
560 /* whole option list or string list is in UTF-8 */
561 isutf8 = pdc_is_lastopt_utf8(resopts);
562
563 /* Encoding */
564 if (ishypertext)
565 {
566 /* Initialize */
567 if (!isutf8)
568 {
569 if (enc < 0 && enc != pdc_unicode && enc != pdc_cid)
570 enc = pdf_get_hypertextencoding(p, "auto", &codepage,
571 pdc_true);
572 if (enc >= 0)
573 inev = pdc_get_encoding_vector(p->pdc, enc);
574 }
575
576 /* ugly solution of bug #2344 */
577 if (ishypertext == pdc_true)
578 {
579 outev = pdc_get_encoding_vector(p->pdc, pdc_pdfdoc);
580
581 /* conversion to PDFDocEncoding if possible */
582 convflags |= PDC_CONV_TRYBYTES;
583 }
584 else if (ishypertext == pdc_undef)
585 {
586 /* filename as hypertext */
587 outtextformat = PDC_UTF8;
588 convflags |= PDC_CONV_TRY7BYTES;
589 }
590 }
591 else
592 {
593 if (enc == pdc_invalidenc)
594 {
595 if (fieldname)
596 {
597 pdc_cleanup_optionlist(p->pdc, resopts);
598 pdc_error(p->pdc, PDF_E_FF_FONTMISSING, fieldname, 0, 0, 0);
599 }
600 return 0;
601 }
602 else if (enc >= 0 && !isutf8)
603 {
604 /* bug #2069: always conversion to UTF-16BE */
605 inev = pdc_get_encoding_vector(p->pdc, enc);
606 }
607 }
608
609 if (logg1)
610 {
611 if (isutf8)
612 {
613 pdc_logg(p->pdc, "\tOption \"%s\" is "PDC_UTF8_STRG" encoded\n",
614 keyword);
615 }
616 else
617 {
618 pdc_logg(p->pdc, "\tOption \"%s\" is %s encoded\n",
619 keyword, pdc_get_user_encoding(p->pdc, enc));
620 }
621 }
622
623 for (i = 0; i < ns; i++)
624 {
625 string = (pdc_byte *) strlist[i];
626
627 {
628 if (ishypertext || isutf8 || inev != NULL)
629 {
630 intextformat = isutf8 ? PDC_UTF8 : pdc_bytes;
631
632 if (pdc_logg_is_enabled(p->pdc, 3, trc_text))
633 convflags |= PDC_CONV_LOGGING;
634 pdf_set_convertflags(p, &convflags);
635 textformat = outtextformat;
636 pdc_convert_string(p->pdc, intextformat, codepage, inev,
637 string, (int) strlen((char *) string),
638 &textformat, outev, &string, &outlen,
639 convflags, pdc_true);
640 pdc_free(p->pdc, strlist[i]);
641 strlist[i] = (char *) string;
642 }
643 }
644 }
645
646 if (text)
647 *text = strlist[0];
648 else
649 *textlist = strlist;
650
651 if (fieldname)
652 {
653 strlist = (char **) pdc_save_lastopt(resopts, PDC_OPT_SAVEALL);
654 pdf_insert_stringlist(p, strlist, ns);
655 }
656 }
657
658 return ns;
659 }
660
661 char *
pdf_get_opt_filename(PDF * p,const char * keyword,pdc_resopt * resopts,pdc_encoding enc,int codepage)662 pdf_get_opt_filename(PDF *p, const char *keyword, pdc_resopt *resopts,
663 pdc_encoding enc, int codepage)
664 {
665 pdc_bool logg1 = pdc_logg_is_enabled(p->pdc, 1, trc_optlist);
666 pdc_bool logg3 = pdc_logg_is_enabled(p->pdc, 3, trc_text);
667 pdc_byte *filename = NULL;
668 char **strlist;
669
670 if (pdc_get_optvalues(keyword, resopts, NULL, &strlist))
671 {
672 pdc_encodingvector *inev = NULL, *outev = NULL;
673 pdc_text_format intextformat = pdc_bytes;
674 pdc_text_format outtextformat = pdc_utf16; /* sic! */
675 int convflags = PDC_CONV_NOBOM | PDC_CONV_TRYBYTES | PDC_CONV_NEWALLOC;
676 pdc_bool isutf8;
677 int ic, outlen;
678
679 /* whole option list or string list is in UTF-8 */
680 isutf8 = pdc_is_lastopt_utf8(resopts);
681
682 if (!isutf8)
683 {
684 if (enc < 0 && enc != pdc_unicode && enc != pdc_cid)
685 enc = pdf_get_hypertextencoding(p, "auto", &codepage,
686 pdc_true);
687 if (enc >= 0)
688 inev = pdc_get_encoding_vector(p->pdc, enc);
689 }
690 else
691 {
692 intextformat = PDC_UTF8;
693 }
694
695 if (logg1)
696 {
697 if (isutf8)
698 {
699 pdc_logg(p->pdc, "\tOption \"%s\" is "PDC_UTF8_STRG" encoded\n",
700 keyword);
701 }
702 else
703 {
704 pdc_logg(p->pdc, "\tOption \"%s\" is %s encoded\n",
705 keyword, pdc_get_user_encoding(p->pdc, enc));
706 }
707 }
708
709 outev = pdc_get_encoding_vector(p->pdc, pdc_winansi);
710
711 if (logg3)
712 convflags |= PDC_CONV_LOGGING;
713 pdf_set_convertflags(p, &convflags);
714
715 pdc_convert_string(p->pdc, intextformat, codepage, inev,
716 (pdc_byte *) strlist[0], (int) strlen(strlist[0]),
717 &outtextformat, outev, &filename, &outlen,
718 convflags, pdc_true);
719
720 if (outtextformat == pdc_utf16)
721 {
722 pdc_ushort uv, *unifilename = (pdc_ushort *) filename;
723 int code;
724
725 if (p->compatibility < PDC_1_7)
726 pdc_error(p->pdc, PDC_E_IO_UNSUPP_PDFUNINAME, 0, 0, 0, 0);
727
728 /* we must replace non-WinAnsi characters by period
729 * and omit the BOM to get a WinAnsi string.
730 */
731 outlen /= 2;
732 for (ic = 0; ic < outlen; ic++)
733 {
734 uv = unifilename[ic];
735
736 code = pdc_get_encoding_bytecode(p->pdc, outev, uv);
737 if (code <= 0)
738 uv = PDC_UNICODE_PERIOD;
739
740 filename[ic] = (char) uv;
741 }
742 filename[ic] = 0;
743 }
744
745 if (logg3)
746 pdc_logg_hexdump(p->pdc, "output filename", "\t\t",
747 (char *) filename, strlen((char *) filename));
748 }
749
750 return (char *) filename;
751 }
752
753 char *
pdf_get_opt_utf8name(PDF * p,const char * keyword,pdc_resopt * resopts)754 pdf_get_opt_utf8name(PDF *p, const char *keyword, pdc_resopt *resopts)
755 {
756 char **strlist = NULL;
757 char *utf8name = NULL;
758
759 if (pdc_get_opt_utf8strings(p->pdc, keyword, resopts, PDC_OPT_SAVE1ELEM,
760 &strlist))
761 {
762 utf8name = strlist[0];
763 }
764
765 return utf8name;
766 }
767
768
769 /* -------------------------- errorpolicy -------------------------------*/
770
771 pdc_bool
pdf_get_errorpolicy(PDF * p,pdc_resopt * resopts,pdc_bool verbose)772 pdf_get_errorpolicy(PDF *p, pdc_resopt *resopts, pdc_bool verbose)
773 {
774 int errpol = (int) p->errorpolicy;
775
776 if (resopts != NULL)
777 pdc_get_optvalues("errorpolicy", resopts, &errpol, NULL);
778
779 if (errpol != (int) errpol_legacy)
780 verbose = errpol;
781
782 return verbose;
783 }
784
785
786 /* -------------------------- handle check -------------------------------*/
787
788 int
pdf_check_opt_handle(void * opaque,int handle,pdc_opttype type)789 pdf_check_opt_handle(void *opaque, int handle, pdc_opttype type)
790 {
791 PDF *p = (PDF*)opaque;
792 int minval = 0, maxval = 0;
793 pdc_bool empty = pdc_false;
794
795 switch (type)
796 {
797
798 case pdc_actionhandle:
799 maxval = pdf_get_max_action(p);
800 break;
801
802 case pdc_bookmarkhandle:
803 maxval = p->outline_count;
804 break;
805
806 case pdc_colorhandle:
807 maxval = p->colorspaces_number - 1;
808 break;
809
810
811 case pdc_fonthandle:
812 maxval = p->fonts_number - 1;
813 empty = !pdf_isvalid_font(p, handle);
814 break;
815
816 case pdc_gstatehandle:
817 maxval = p->extgstates_number - 1;
818 break;
819
820
821 case pdc_imagehandle:
822 maxval = p->images_capacity - 1;
823 if (handle >= minval && handle <= maxval &&
824 (!p->images[handle].in_use ||
825 p->xobjects[p->images[handle].no].type == pdi_xobject))
826 empty = pdc_true;
827 break;
828
829
830 case pdc_pagehandle:
831 maxval = p->images_capacity - 1;
832 if (handle >= minval && handle <= maxval &&
833 (!p->images[handle].in_use ||
834 p->xobjects[p->images[handle].no].type != pdi_xobject))
835 empty = pdc_true;
836 break;
837
838 case pdc_patternhandle:
839 maxval = p->pattern_number - 1;
840 break;
841
842 case pdc_shadinghandle:
843 maxval = p->shadings_number - 1;
844 break;
845
846
847 case pdc_templatehandle:
848 maxval = p->images_capacity - 1;
849 if (handle >= minval && handle <= maxval &&
850 (!p->images[handle].in_use ||
851 p->xobjects[p->images[handle].no].type != form_xobject))
852 empty = pdc_true;
853 break;
854
855
856 case pdc_stringhandle:
857 if (p->utilstrlist_index == -1)
858 empty = pdc_true;
859 maxval = p->utilstring_number - 1;
860 break;
861
862 default:
863 break;
864 }
865
866 if (handle < minval || handle > maxval || empty)
867 return PDC_E_ILLARG_HANDLE;
868
869 return 0;
870 }
871
872 void
pdf_check_handle(PDF * p,int handle,pdc_opttype type)873 pdf_check_handle(PDF *p, int handle, pdc_opttype type)
874 {
875 if (pdf_check_opt_handle(p, handle, type))
876 {
877 if (p->pdc->hastobepos && type != pdc_stringhandle)
878 handle++;
879
880 pdc_error(p->pdc, PDC_E_ILLARG_HANDLE,
881 pdc_errprintf(p->pdc, "%.*s", PDC_ERR_MAXSTRLEN,
882 pdc_get_handletype(type)),
883 pdc_errprintf(p->pdc, "%d", handle), 0, 0);
884 }
885 }
886
887 void
pdf_set_clientdata(PDF * p,pdc_clientdata * cdata)888 pdf_set_clientdata(PDF *p, pdc_clientdata *cdata)
889 {
890 memset(cdata, 0, sizeof(pdc_clientdata));
891
892 cdata->maxaction = pdf_get_max_action(p);
893 cdata->maxbookmark = p->outline_count;
894 cdata->maxcolor = p->colorspaces_number - 1;
895 cdata->maxdocument = p->pdi_capacity - 1;
896 cdata->maxfont = p->fonts_number - 1;
897 cdata->maxgstate = p->extgstates_number - 1;
898 cdata->maximage = p->images_capacity - 1;
899 cdata->maxpage = p->images_capacity - 1;
900 cdata->maxpattern = p->pattern_number - 1;
901 cdata->maxshading = p->shadings_number - 1;
902 cdata->maxtemplate = p->images_capacity - 1;
903 cdata->maxstring = p->utilstring_number - 1;
904
905 cdata->compatibility = p->compatibility;
906 }
907