1/*
2 * << Haru Free PDF Library >> -- hpdf_doc.c
3 *
4 * URL: http://libharu.org
5 *
6 * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
7 * Copyright (c) 2007-2009 Antony Dovgal <tony@daylessday.org>
8 *
9 * Permission to use, copy, modify, distribute and sell this software
10 * and its documentation for any purpose is hereby granted without fee,
11 * provided that the above copyright notice appear in all copies and
12 * that both that copyright notice and this permission notice appear
13 * in supporting documentation.
14 * It is provided "as is" without express or implied warranty.
15 *
16 */
17
18
19#include "hpdf_conf.h"
20#include "hpdf_utils.h"
21#include "hpdf_encryptdict.h"
22#include "hpdf_namedict.h"
23#include "hpdf_destination.h"
24#include "hpdf_info.h"
25#include "hpdf_page_label.h"
26#include "hpdf.h"
27
28
29static const char * const HPDF_VERSION_STR[6] = {
30 "%PDF-1.2\012%\267\276\255\252\012",
31 "%PDF-1.3\012%\267\276\255\252\012",
32 "%PDF-1.4\012%\267\276\255\252\012",
33 "%PDF-1.5\012%\267\276\255\252\012",
34 "%PDF-1.6\012%\267\276\255\252\012",
35 "%PDF-1.7\012%\267\276\255\252\012"
36};
37
38
39static HPDF_STATUS
40WriteHeader (HPDF_Doc pdf,
41 HPDF_Stream stream);
42
43
44static HPDF_STATUS
45PrepareTrailer (HPDF_Doc pdf);
46
47
48static void
49FreeEncoderList (HPDF_Doc pdf);
50
51
52static void
53FreeFontDefList (HPDF_Doc pdf);
54
55
56static void
57CleanupFontDefList (HPDF_Doc pdf);
58
59
60static HPDF_Dict
61GetInfo (HPDF_Doc pdf);
62
63static HPDF_STATUS
64InternalSaveToStream (HPDF_Doc pdf,
65 HPDF_Stream stream);
66
67static const char*
68LoadType1FontFromStream (HPDF_Doc pdf,
69 HPDF_Stream afmdata,
70 HPDF_Stream pfmdata);
71
72
73static const char*
74LoadTTFontFromStream (HPDF_Doc pdf,
75 HPDF_Stream font_data,
76 HPDF_BOOL embedding,
77 const char *file_name);
78
79
80static const char*
81LoadTTFontFromStream2 (HPDF_Doc pdf,
82 HPDF_Stream font_data,
83 HPDF_UINT index,
84 HPDF_BOOL embedding,
85 const char *file_name);
86
87
88/*---------------------------------------------------------------------------*/
89
90HPDF_EXPORT(const char *)
91HPDF_GetVersion (void)
92{
93 return HPDF_VERSION_TEXT;
94}
95
96
97HPDF_BOOL
98HPDF_Doc_Validate (HPDF_Doc pdf)
99{
100 HPDF_PTRACE ((" HPDF_Doc_Validate\n"));
101
102 if (!pdf || pdf->sig_bytes != HPDF_SIG_BYTES)
103 return HPDF_FALSE;
104 else
105 return HPDF_TRUE;
106}
107
108
109HPDF_EXPORT(HPDF_BOOL)
110HPDF_HasDoc (HPDF_Doc pdf)
111{
112 HPDF_PTRACE ((" HPDF_HasDoc\n"));
113
114 if (!pdf || pdf->sig_bytes != HPDF_SIG_BYTES)
115 return HPDF_FALSE;
116
117 if (!pdf->catalog || pdf->error.error_no != HPDF_NOERROR) {
118 HPDF_RaiseError (&pdf->error, HPDF_INVALID_DOCUMENT, 0);
119 return HPDF_FALSE;
120 } else
121 return HPDF_TRUE;
122}
123
124
125HPDF_EXPORT(HPDF_Doc)
126HPDF_New (HPDF_Error_Handler user_error_fn,
127 void *user_data)
128{
129 HPDF_PTRACE ((" HPDF_New\n"));
130
131 return HPDF_NewEx (user_error_fn, NULL, NULL, 0, user_data);
132}
133
134
135HPDF_EXPORT(HPDF_Doc)
136HPDF_NewEx (HPDF_Error_Handler user_error_fn,
137 HPDF_Alloc_Func user_alloc_fn,
138 HPDF_Free_Func user_free_fn,
139 HPDF_UINT mem_pool_buf_size,
140 void *user_data)
141{
142 HPDF_Doc pdf;
143 HPDF_MMgr mmgr;
144 HPDF_Error_Rec tmp_error;
145
146 HPDF_PTRACE ((" HPDF_NewEx\n"));
147
148 /* initialize temporary-error object */
149 HPDF_Error_Init (&tmp_error, user_data);
150
151 /* create memory-manager object */
152 mmgr = HPDF_MMgr_New (&tmp_error, mem_pool_buf_size, user_alloc_fn,
153 user_free_fn);
154 if (!mmgr) {
155 HPDF_CheckError (&tmp_error);
156 return NULL;
157 }
158
159 /* now create pdf_doc object */
160 pdf = HPDF_GetMem (mmgr, sizeof (HPDF_Doc_Rec));
161 if (!pdf) {
162 HPDF_MMgr_Free (mmgr);
163 HPDF_CheckError (&tmp_error);
164 return NULL;
165 }
166
167 HPDF_MemSet (pdf, 0, sizeof (HPDF_Doc_Rec));
168 pdf->sig_bytes = HPDF_SIG_BYTES;
169 pdf->mmgr = mmgr;
170 pdf->pdf_version = HPDF_VER_13;
171 pdf->compression_mode = HPDF_COMP_NONE;
172
173 /* copy the data of temporary-error object to the one which is
174 included in pdf_doc object */
175 pdf->error = tmp_error;
176
177 /* switch the error-object of memory-manager */
178 mmgr->error = &pdf->error;
179
180 if (HPDF_NewDoc (pdf) != HPDF_OK) {
181 HPDF_Free (pdf);
182 HPDF_CheckError (&tmp_error);
183 return NULL;
184 }
185
186 pdf->error.error_fn = user_error_fn;
187
188 return pdf;
189}
190
191
192HPDF_EXPORT(void)
193HPDF_Free (HPDF_Doc pdf)
194{
195 HPDF_PTRACE ((" HPDF_Free\n"));
196
197 if (pdf) {
198 HPDF_MMgr mmgr = pdf->mmgr;
199
200 HPDF_FreeDocAll (pdf);
201
202 pdf->sig_bytes = 0;
203
204 HPDF_FreeMem (mmgr, pdf);
205 HPDF_MMgr_Free (mmgr);
206 }
207}
208
209
210HPDF_EXPORT(HPDF_STATUS)
211HPDF_NewDoc (HPDF_Doc pdf)
212{
213 char buf[HPDF_TMP_BUF_SIZ];
214 char *ptr = buf;
215 char *eptr = buf + HPDF_TMP_BUF_SIZ - 1;
216 const char *version;
217
218 HPDF_PTRACE ((" HPDF_NewDoc\n"));
219
220 if (!HPDF_Doc_Validate (pdf))
221 return HPDF_DOC_INVALID_OBJECT;
222
223 HPDF_FreeDoc (pdf);
224
225 pdf->xref = HPDF_Xref_New (pdf->mmgr, 0);
226 if (!pdf->xref)
227 return HPDF_CheckError (&pdf->error);
228
229 pdf->trailer = pdf->xref->trailer;
230
231 pdf->font_mgr = HPDF_List_New (pdf->mmgr, HPDF_DEF_ITEMS_PER_BLOCK);
232 if (!pdf->font_mgr)
233 return HPDF_CheckError (&pdf->error);
234
235 if (!pdf->fontdef_list) {
236 pdf->fontdef_list = HPDF_List_New (pdf->mmgr,
237 HPDF_DEF_ITEMS_PER_BLOCK);
238 if (!pdf->fontdef_list)
239 return HPDF_CheckError (&pdf->error);
240 }
241
242 if (!pdf->encoder_list) {
243 pdf->encoder_list = HPDF_List_New (pdf->mmgr,
244 HPDF_DEF_ITEMS_PER_BLOCK);
245 if (!pdf->encoder_list)
246 return HPDF_CheckError (&pdf->error);
247 }
248
249 pdf->catalog = HPDF_Catalog_New (pdf->mmgr, pdf->xref);
250 if (!pdf->catalog)
251 return HPDF_CheckError (&pdf->error);
252
253 pdf->root_pages = HPDF_Catalog_GetRoot (pdf->catalog);
254 if (!pdf->root_pages)
255 return HPDF_CheckError (&pdf->error);
256
257 pdf->page_list = HPDF_List_New (pdf->mmgr, HPDF_DEF_PAGE_LIST_NUM);
258 if (!pdf->page_list)
259 return HPDF_CheckError (&pdf->error);
260
261 pdf->cur_pages = pdf->root_pages;
262
263 ptr = (char *)HPDF_StrCpy (ptr, (const char *)"Haru Free PDF Library ", eptr);
264 version = HPDF_GetVersion ();
265 HPDF_StrCpy (ptr, version, eptr);
266
267 if (HPDF_SetInfoAttr (pdf, HPDF_INFO_PRODUCER, buf) != HPDF_OK)
268 return HPDF_CheckError (&pdf->error);
269
270 return HPDF_OK;
271}
272
273
274HPDF_EXPORT(void)
275HPDF_FreeDoc (HPDF_Doc pdf)
276{
277 HPDF_PTRACE ((" HPDF_FreeDoc\n"));
278
279 if (HPDF_Doc_Validate (pdf)) {
280 if (pdf->xref) {
281 HPDF_Xref_Free (pdf->xref);
282 pdf->xref = NULL;
283 }
284
285 if (pdf->font_mgr) {
286 HPDF_List_Free (pdf->font_mgr);
287 pdf->font_mgr = NULL;
288 }
289
290 if (pdf->fontdef_list)
291 CleanupFontDefList (pdf);
292
293 HPDF_MemSet(pdf->ttfont_tag, 0, 6);
294
295 pdf->pdf_version = HPDF_VER_13;
296 pdf->outlines = NULL;
297 pdf->catalog = NULL;
298 pdf->root_pages = NULL;
299 pdf->cur_pages = NULL;
300 pdf->cur_page = NULL;
301 pdf->encrypt_on = HPDF_FALSE;
302 pdf->cur_page_num = 0;
303 pdf->cur_encoder = NULL;
304 pdf->def_encoder = NULL;
305 pdf->page_per_pages = 0;
306
307 if (pdf->page_list) {
308 HPDF_List_Free (pdf->page_list);
309 pdf->page_list = NULL;
310 }
311
312 pdf->encrypt_dict = NULL;
313 pdf->info = NULL;
314
315 HPDF_Error_Reset (&pdf->error);
316
317 if (pdf->stream) {
318 HPDF_Stream_Free (pdf->stream);
319 pdf->stream = NULL;
320 }
321 }
322}
323
324
325HPDF_EXPORT(void)
326HPDF_FreeDocAll (HPDF_Doc pdf)
327{
328 HPDF_PTRACE ((" HPDF_FreeDocAll\n"));
329
330 if (HPDF_Doc_Validate (pdf)) {
331 HPDF_FreeDoc (pdf);
332
333 if (pdf->fontdef_list)
334 FreeFontDefList (pdf);
335
336 if (pdf->encoder_list)
337 FreeEncoderList (pdf);
338
339 pdf->compression_mode = HPDF_COMP_NONE;
340
341 HPDF_Error_Reset (&pdf->error);
342 }
343}
344
345
346HPDF_EXPORT(HPDF_STATUS)
347HPDF_SetPagesConfiguration (HPDF_Doc pdf,
348 HPDF_UINT page_per_pages)
349{
350 HPDF_PTRACE ((" HPDF_SetPagesConfiguration\n"));
351
352 if (!HPDF_HasDoc (pdf))
353 return HPDF_INVALID_DOCUMENT;
354
355 if (pdf->cur_page)
356 return HPDF_RaiseError (&pdf->error, HPDF_INVALID_DOCUMENT_STATE, 0);
357
358 if (page_per_pages > HPDF_LIMIT_MAX_ARRAY)
359 return HPDF_RaiseError (&pdf->error, HPDF_INVALID_PARAMETER, 0);
360
361 if (pdf->cur_pages == pdf->root_pages) {
362 pdf->cur_pages = HPDF_Doc_AddPagesTo (pdf, pdf->root_pages);
363 if (!pdf->cur_pages)
364 return pdf->error.error_no;
365 pdf->cur_page_num = 0;
366 }
367
368 pdf->page_per_pages = page_per_pages;
369
370 return HPDF_OK;
371}
372
373
374static HPDF_STATUS
375WriteHeader (HPDF_Doc pdf,
376 HPDF_Stream stream)
377{
378 HPDF_UINT idx = (HPDF_INT)pdf->pdf_version;
379
380 HPDF_PTRACE ((" WriteHeader\n"));
381
382 if (HPDF_Stream_WriteStr (stream, HPDF_VERSION_STR[idx]) != HPDF_OK)
383 return pdf->error.error_no;
384
385 return HPDF_OK;
386}
387
388
389static HPDF_STATUS
390PrepareTrailer (HPDF_Doc pdf)
391{
392 HPDF_PTRACE ((" PrepareTrailer\n"));
393
394 if (HPDF_Dict_Add (pdf->trailer, "Root", pdf->catalog) != HPDF_OK)
395 return pdf->error.error_no;
396
397 if (HPDF_Dict_Add (pdf->trailer, "Info", pdf->info) != HPDF_OK)
398 return pdf->error.error_no;
399
400 return HPDF_OK;
401}
402
403
404HPDF_STATUS
405HPDF_Doc_SetEncryptOn (HPDF_Doc pdf)
406{
407 HPDF_PTRACE ((" HPDF_Doc_SetEncryptOn\n"));
408
409 if (pdf->encrypt_on)
410 return HPDF_OK;
411
412 if (!pdf->encrypt_dict)
413 return HPDF_SetError (&pdf->error, HPDF_DOC_ENCRYPTDICT_NOT_FOUND,
414 0);
415
416 if (pdf->encrypt_dict->header.obj_id == HPDF_OTYPE_NONE)
417 if (HPDF_Xref_Add (pdf->xref, pdf->encrypt_dict) != HPDF_OK)
418 return pdf->error.error_no;
419
420 if (HPDF_Dict_Add (pdf->trailer, "Encrypt", pdf->encrypt_dict) != HPDF_OK)
421 return pdf->error.error_no;
422
423 pdf->encrypt_on = HPDF_TRUE;
424
425 return HPDF_OK;
426}
427
428HPDF_EXPORT(HPDF_STATUS)
429HPDF_SetPassword (HPDF_Doc pdf,
430 const char *owner_passwd,
431 const char *user_passwd)
432{
433 HPDF_PTRACE ((" HPDF_SetPassword\n"));
434
435 if (!HPDF_HasDoc (pdf))
436 return HPDF_DOC_INVALID_OBJECT;
437
438 if (!pdf->encrypt_dict) {
439 pdf->encrypt_dict = HPDF_EncryptDict_New (pdf->mmgr, pdf->xref);
440
441 if (!pdf->encrypt_dict)
442 return HPDF_CheckError (&pdf->error);
443 }
444
445 if (HPDF_EncryptDict_SetPassword (pdf->encrypt_dict, owner_passwd,
446 user_passwd) != HPDF_OK)
447 return HPDF_CheckError (&pdf->error);
448
449 return HPDF_Doc_SetEncryptOn (pdf);
450}
451
452
453HPDF_EXPORT(HPDF_STATUS)
454HPDF_SetPermission (HPDF_Doc pdf,
455 HPDF_UINT permission)
456{
457 HPDF_Encrypt e;
458
459 HPDF_PTRACE ((" HPDF_SetPermission\n"));
460
461 if (!HPDF_HasDoc (pdf))
462 return HPDF_DOC_INVALID_OBJECT;
463
464 e = HPDF_EncryptDict_GetAttr (pdf->encrypt_dict);
465
466 if (!e)
467 return HPDF_RaiseError (&pdf->error,
468 HPDF_DOC_ENCRYPTDICT_NOT_FOUND, 0);
469 else
470 e->permission = permission;
471
472 return HPDF_OK;
473}
474
475
476HPDF_EXPORT(HPDF_STATUS)
477HPDF_SetEncryptionMode (HPDF_Doc pdf,
478 HPDF_EncryptMode mode,
479 HPDF_UINT key_len)
480{
481 HPDF_Encrypt e;
482
483 HPDF_PTRACE ((" HPDF_SetEncryptionMode\n"));
484
485 if (!HPDF_Doc_Validate (pdf))
486 return HPDF_DOC_INVALID_OBJECT;
487
488 e = HPDF_EncryptDict_GetAttr (pdf->encrypt_dict);
489
490 if (!e)
491 return HPDF_RaiseError (&pdf->error,
492 HPDF_DOC_ENCRYPTDICT_NOT_FOUND, 0);
493 else {
494 if (mode == HPDF_ENCRYPT_R2)
495 e->key_len = 5;
496 else {
497 /* if encryption mode is specified revision-3, the version of
498 * pdf file is set to 1.4
499 */
500 pdf->pdf_version = HPDF_VER_14;
501
502 if (key_len >= 5 && key_len <= 16)
503 e->key_len = key_len;
504 else if (key_len == 0)
505 e->key_len = 16;
506 else
507 return HPDF_RaiseError (&pdf->error,
508 HPDF_INVALID_ENCRYPT_KEY_LEN, 0);
509 }
510 e->mode = mode;
511 }
512
513 return HPDF_OK;
514}
515
516
517HPDF_STATUS
518HPDF_Doc_SetEncryptOff (HPDF_Doc pdf)
519{
520 HPDF_PTRACE ((" HPDF_Doc_SetEncryptOff\n"));
521
522 if (!pdf->encrypt_on)
523 return HPDF_OK;
524
525 /* if encrypy-dict object is registered to cross-reference-table,
526 * replace it to null-object.
527 * additionally remove encrypt-dict object from trailer-object.
528 */
529 if (pdf->encrypt_dict) {
530 HPDF_UINT obj_id = pdf->encrypt_dict->header.obj_id;
531
532 if (obj_id & HPDF_OTYPE_INDIRECT) {
533 HPDF_XrefEntry entry;
534 HPDF_Null null_obj;
535
536 HPDF_Dict_RemoveElement (pdf->trailer, "Encrypt");
537
538 entry = HPDF_Xref_GetEntryByObjectId (pdf->xref,
539 obj_id & 0x00FFFFFF);
540
541 if (!entry) {
542 return HPDF_SetError (&pdf->error,
543 HPDF_DOC_ENCRYPTDICT_NOT_FOUND, 0);
544 }
545
546 null_obj = HPDF_Null_New (pdf->mmgr);
547 if (!null_obj)
548 return pdf->error.error_no;
549
550 entry->obj = null_obj;
551 null_obj->header.obj_id = obj_id | HPDF_OTYPE_INDIRECT;
552
553 pdf->encrypt_dict->header.obj_id = HPDF_OTYPE_NONE;
554 }
555 }
556
557 pdf->encrypt_on = HPDF_FALSE;
558 return HPDF_OK;
559}
560
561
562HPDF_STATUS
563HPDF_Doc_PrepareEncryption (HPDF_Doc pdf)
564{
565 HPDF_Encrypt e= HPDF_EncryptDict_GetAttr (pdf->encrypt_dict);
566 HPDF_Dict info = GetInfo (pdf);
567 HPDF_Array id;
568
569 if (!e)
570 return HPDF_DOC_ENCRYPTDICT_NOT_FOUND;
571
572 if (!info)
573 return pdf->error.error_no;
574
575 if (HPDF_EncryptDict_Prepare (pdf->encrypt_dict, info, pdf->xref) !=
576 HPDF_OK)
577 return pdf->error.error_no;
578
579 /* reset 'ID' to trailer-dictionary */
580 id = HPDF_Dict_GetItem (pdf->trailer, "ID", HPDF_OCLASS_ARRAY);
581 if (!id) {
582 id = HPDF_Array_New (pdf->mmgr);
583
584 if (!id || HPDF_Dict_Add (pdf->trailer, "ID", id) != HPDF_OK)
585 return pdf->error.error_no;
586 } else
587 HPDF_Array_Clear (id);
588
589 if (HPDF_Array_Add (id, HPDF_Binary_New (pdf->mmgr, e->encrypt_id,
590 HPDF_ID_LEN)) != HPDF_OK)
591 return pdf->error.error_no;
592
593 if (HPDF_Array_Add (id, HPDF_Binary_New (pdf->mmgr, e->encrypt_id,
594 HPDF_ID_LEN)) != HPDF_OK)
595 return pdf->error.error_no;
596
597 return HPDF_OK;
598}
599
600
601static HPDF_STATUS
602InternalSaveToStream (HPDF_Doc pdf,
603 HPDF_Stream stream)
604{
605 HPDF_STATUS ret;
606
607 if ((ret = WriteHeader (pdf, stream)) != HPDF_OK)
608 return ret;
609
610 /* prepare trailer */
611 if ((ret = PrepareTrailer (pdf)) != HPDF_OK)
612 return ret;
613
614 /* prepare encription */
615 if (pdf->encrypt_on) {
616 HPDF_Encrypt e= HPDF_EncryptDict_GetAttr (pdf->encrypt_dict);
617
618 if ((ret = HPDF_Doc_PrepareEncryption (pdf)) != HPDF_OK)
619 return ret;
620
621 if ((ret = HPDF_Xref_WriteToStream (pdf->xref, stream, e)) != HPDF_OK)
622 return ret;
623 } else {
624 if ((ret = HPDF_Xref_WriteToStream (pdf->xref, stream, NULL)) !=
625 HPDF_OK)
626 return ret;
627 }
628
629 return HPDF_OK;
630}
631
632
633HPDF_EXPORT(HPDF_STATUS)
634HPDF_SaveToStream (HPDF_Doc pdf)
635{
636 HPDF_PTRACE ((" HPDF_SaveToStream\n"));
637
638 if (!HPDF_HasDoc (pdf))
639 return HPDF_INVALID_DOCUMENT;
640
641 if (!pdf->stream)
642 pdf->stream = HPDF_MemStream_New (pdf->mmgr, HPDF_STREAM_BUF_SIZ);
643
644 if (!HPDF_Stream_Validate (pdf->stream))
645 return HPDF_RaiseError (&pdf->error, HPDF_INVALID_STREAM, 0);
646
647 HPDF_MemStream_FreeData (pdf->stream);
648
649 if (InternalSaveToStream (pdf, pdf->stream) != HPDF_OK)
650 return HPDF_CheckError (&pdf->error);
651
652 return HPDF_OK;
653}
654
655HPDF_EXPORT(HPDF_STATUS)
656HPDF_GetContents (HPDF_Doc pdf,
657 HPDF_BYTE *buf,
658 HPDF_UINT32 *size)
659{
660 HPDF_Stream stream;
661 HPDF_UINT isize = *size;
662 HPDF_STATUS ret;
663
664 HPDF_PTRACE ((" HPDF_GetContents\n"));
665
666 if (!HPDF_HasDoc (pdf)) {
667 return HPDF_INVALID_DOCUMENT;
668 }
669
670 stream = HPDF_MemStream_New (pdf->mmgr, HPDF_STREAM_BUF_SIZ);
671
672 if (!stream) {
673 return HPDF_CheckError (&pdf->error);
674 }
675
676 if (InternalSaveToStream (pdf, stream) != HPDF_OK) {
677 HPDF_Stream_Free (stream);
678 return HPDF_CheckError (&pdf->error);
679 }
680
681 ret = HPDF_Stream_Read (stream, buf, &isize);
682
683 *size = isize;
684 HPDF_Stream_Free (stream);
685
686 return ret;
687}
688
689HPDF_EXPORT(HPDF_UINT32)
690HPDF_GetStreamSize (HPDF_Doc pdf)
691{
692 HPDF_PTRACE ((" HPDF_GetStreamSize\n"));
693
694 if (!HPDF_HasDoc (pdf))
695 return HPDF_INVALID_DOCUMENT;
696
697 if (!HPDF_Stream_Validate (pdf->stream))
698 return 0;
699
700 return HPDF_Stream_Size(pdf->stream);
701}
702
703
704HPDF_EXPORT(HPDF_STATUS)
705HPDF_ReadFromStream (HPDF_Doc pdf,
706 HPDF_BYTE *buf,
707 HPDF_UINT32 *size)
708{
709 HPDF_UINT isize = *size;
710 HPDF_STATUS ret;
711
712 if (!HPDF_HasDoc (pdf))
713 return HPDF_INVALID_DOCUMENT;
714
715 if (!HPDF_Stream_Validate (pdf->stream))
716 return HPDF_RaiseError (&pdf->error, HPDF_INVALID_OPERATION, 0);
717
718 if (*size == 0)
719 return HPDF_RaiseError (&pdf->error, HPDF_INVALID_PARAMETER, 0);
720
721 ret = HPDF_Stream_Read (pdf->stream, buf, &isize);
722
723 *size = isize;
724
725 if (ret != HPDF_OK)
726 HPDF_CheckError (&pdf->error);
727
728 return ret;
729}
730
731
732HPDF_EXPORT(HPDF_STATUS)
733HPDF_ResetStream (HPDF_Doc pdf)
734{
735 if (!HPDF_HasDoc (pdf))
736 return HPDF_INVALID_DOCUMENT;
737
738 if (!HPDF_Stream_Validate (pdf->stream))
739 return HPDF_RaiseError (&pdf->error, HPDF_INVALID_OPERATION, 0);
740
741 return HPDF_Stream_Seek (pdf->stream, 0, HPDF_SEEK_SET);
742}
743
744
745HPDF_EXPORT(HPDF_STATUS)
746HPDF_SaveToFile (HPDF_Doc pdf,
747 const char *file_name)
748{
749 HPDF_Stream stream;
750
751 HPDF_PTRACE ((" HPDF_SaveToFile\n"));
752
753 if (!HPDF_HasDoc (pdf))
754 return HPDF_INVALID_DOCUMENT;
755
756 stream = HPDF_FileWriter_New (pdf->mmgr, file_name);
757 if (!stream)
758 return HPDF_CheckError (&pdf->error);
759
760 InternalSaveToStream (pdf, stream);
761
762 HPDF_Stream_Free (stream);
763
764 return HPDF_CheckError (&pdf->error);
765}
766
767
768HPDF_EXPORT(HPDF_Page)
769HPDF_GetCurrentPage (HPDF_Doc pdf)
770{
771 HPDF_PTRACE ((" HPDF_GetCurrentPage\n"));
772
773 if (!HPDF_HasDoc (pdf))
774 return NULL;
775
776 return pdf->cur_page;
777}
778
779
780HPDF_EXPORT(HPDF_Page)
781HPDF_GetPageByIndex (HPDF_Doc pdf,
782 HPDF_UINT index)
783{
784 HPDF_Page ret;
785
786 HPDF_PTRACE ((" HPDF_GetPageByIndex\n"));
787
788 if (!HPDF_HasDoc (pdf))
789 return NULL;
790
791 ret = HPDF_List_ItemAt (pdf->page_list, index);
792 if (!ret) {
793 HPDF_RaiseError (&pdf->error, HPDF_INVALID_PAGE_INDEX, 0);
794 return NULL;
795 }
796
797 return ret;
798}
799
800
801HPDF_Pages
802HPDF_Doc_GetCurrentPages (HPDF_Doc pdf)
803{
804 HPDF_PTRACE ((" HPDF_GetCurrentPages\n"));
805
806 if (!HPDF_HasDoc (pdf))
807 return NULL;
808
809 return pdf->cur_pages;
810}
811
812
813HPDF_STATUS
814HPDF_Doc_SetCurrentPages (HPDF_Doc pdf,
815 HPDF_Pages pages)
816{
817 HPDF_PTRACE ((" HPDF_Doc_SetCurrentPages\n"));
818
819 if (!HPDF_HasDoc (pdf))
820 return HPDF_INVALID_DOCUMENT;
821
822 if (!HPDF_Pages_Validate (pages))
823 return HPDF_SetError (&pdf->error, HPDF_INVALID_PAGES, 0);
824
825 /* check whether the pages belong to the pdf */
826 if (pdf->mmgr != pages->mmgr)
827 return HPDF_SetError (&pdf->error, HPDF_INVALID_PAGES, 0);
828
829 pdf->cur_pages = pages;
830
831 return HPDF_OK;
832}
833
834
835HPDF_STATUS
836HPDF_Doc_SetCurrentPage (HPDF_Doc pdf,
837 HPDF_Page page)
838{
839 HPDF_PTRACE ((" HPDF_Doc_SetCurrentPage\n"));
840
841 if (!HPDF_HasDoc (pdf))
842 return HPDF_INVALID_DOCUMENT;
843
844 if (!HPDF_Page_Validate (page))
845 return HPDF_SetError (&pdf->error, HPDF_INVALID_PAGE, 0);
846
847 /* check whether the page belong to the pdf */
848 if (pdf->mmgr != page->mmgr)
849 return HPDF_SetError (&pdf->error, HPDF_INVALID_PAGE, 0);
850
851 pdf->cur_page = page;
852
853 return HPDF_OK;
854}
855
856
857HPDF_EXPORT(HPDF_Page)
858HPDF_AddPage (HPDF_Doc pdf)
859{
860 HPDF_Page page;
861 HPDF_STATUS ret;
862
863 HPDF_PTRACE ((" HPDF_AddPage\n"));
864
865 if (!HPDF_HasDoc (pdf))
866 return NULL;
867
868 if (pdf->page_per_pages) {
869 if (pdf->page_per_pages <= pdf->cur_page_num) {
870 pdf->cur_pages = HPDF_Doc_AddPagesTo (pdf, pdf->root_pages);
871 if (!pdf->cur_pages)
872 return NULL;
873 pdf->cur_page_num = 0;
874 }
875 }
876
877 page = HPDF_Page_New (pdf->mmgr, pdf->xref);
878 if (!page) {
879 HPDF_CheckError (&pdf->error);
880 return NULL;
881 }
882
883 if ((ret = HPDF_Pages_AddKids (pdf->cur_pages, page)) != HPDF_OK) {
884 HPDF_RaiseError (&pdf->error, ret, 0);
885 return NULL;
886 }
887
888 if ((ret = HPDF_List_Add (pdf->page_list, page)) != HPDF_OK) {
889 HPDF_RaiseError (&pdf->error, ret, 0);
890 return NULL;
891 }
892
893 pdf->cur_page = page;
894
895 if (pdf->compression_mode & HPDF_COMP_TEXT)
896 HPDF_Page_SetFilter (page, HPDF_STREAM_FILTER_FLATE_DECODE);
897
898 pdf->cur_page_num++;
899
900 return page;
901}
902
903
904HPDF_Pages
905HPDF_Doc_AddPagesTo (HPDF_Doc pdf,
906 HPDF_Pages parent)
907{
908 HPDF_Pages pages;
909
910 HPDF_PTRACE ((" HPDF_AddPagesTo\n"));
911
912 if (!HPDF_HasDoc (pdf))
913 return NULL;
914
915 if (!HPDF_Pages_Validate (parent)) {
916 HPDF_RaiseError (&pdf->error, HPDF_INVALID_PAGES, 0);
917 return NULL;
918 }
919
920 /* check whether the page belong to the pdf */
921 if (pdf->mmgr != parent->mmgr) {
922 HPDF_RaiseError (&pdf->error, HPDF_INVALID_PAGES, 0);
923 return NULL;
924 }
925
926 pages = HPDF_Pages_New (pdf->mmgr, parent, pdf->xref);
927 if (pages)
928 pdf->cur_pages = pages;
929 else
930 HPDF_CheckError (&pdf->error);
931
932
933 return pages;
934}
935
936
937HPDF_EXPORT(HPDF_Page)
938HPDF_InsertPage (HPDF_Doc pdf,
939 HPDF_Page target)
940{
941 HPDF_Page page;
942 HPDF_STATUS ret;
943
944 HPDF_PTRACE ((" HPDF_InsertPage\n"));
945
946 if (!HPDF_HasDoc (pdf))
947 return NULL;
948
949 if (!HPDF_Page_Validate (target)) {
950 HPDF_RaiseError (&pdf->error, HPDF_INVALID_PAGE, 0);
951 return NULL;
952 }
953
954 /* check whether the page belong to the pdf */
955 if (pdf->mmgr != target->mmgr) {
956 HPDF_RaiseError (&pdf->error, HPDF_INVALID_PAGE, 0);
957 return NULL;
958 }
959
960 page = HPDF_Page_New (pdf->mmgr, pdf->xref);
961 if (!page) {
962 HPDF_CheckError (&pdf->error);
963 return NULL;
964 }
965
966 if ((ret = HPDF_Page_InsertBefore (page, target)) != HPDF_OK) {
967 HPDF_RaiseError (&pdf->error, ret, 0);
968 return NULL;
969 }
970
971 if ((ret = HPDF_List_Insert (pdf->page_list, target, page)) != HPDF_OK) {
972 HPDF_RaiseError (&pdf->error, ret, 0);
973 return NULL;
974 }
975
976 if (pdf->compression_mode & HPDF_COMP_TEXT)
977 HPDF_Page_SetFilter (page, HPDF_STREAM_FILTER_FLATE_DECODE);
978
979 return page;
980}
981
982
983HPDF_EXPORT(HPDF_STATUS)
984HPDF_SetErrorHandler (HPDF_Doc pdf,
985 HPDF_Error_Handler user_error_fn)
986{
987 if (!HPDF_Doc_Validate (pdf))
988 return HPDF_INVALID_DOCUMENT;
989
990 pdf->error.error_fn = user_error_fn;
991
992 return HPDF_OK;
993}
994
995
996/*----- font handling -------------------------------------------------------*/
997
998
999static void
1000FreeFontDefList (HPDF_Doc pdf)
1001{
1002 HPDF_List list = pdf->fontdef_list;
1003 HPDF_UINT i;
1004
1005 HPDF_PTRACE ((" HPDF_Doc_FreeFontDefList\n"));
1006
1007 for (i = 0; i < list->count; i++) {
1008 HPDF_FontDef def = (HPDF_FontDef)HPDF_List_ItemAt (list, i);
1009
1010 HPDF_FontDef_Free (def);
1011 }
1012
1013 HPDF_List_Free (list);
1014
1015 pdf->fontdef_list = NULL;
1016}
1017
1018static void
1019CleanupFontDefList (HPDF_Doc pdf)
1020{
1021 HPDF_List list = pdf->fontdef_list;
1022 HPDF_UINT i;
1023
1024 HPDF_PTRACE ((" CleanupFontDefList\n"));
1025
1026 for (i = 0; i < list->count; i++) {
1027 HPDF_FontDef def = (HPDF_FontDef)HPDF_List_ItemAt (list, i);
1028
1029 HPDF_FontDef_Cleanup (def);
1030 }
1031}
1032
1033
1034HPDF_FontDef
1035HPDF_Doc_FindFontDef (HPDF_Doc pdf,
1036 const char *font_name)
1037{
1038 HPDF_List list = pdf->fontdef_list;
1039 HPDF_UINT i;
1040
1041 HPDF_PTRACE ((" HPDF_Doc_FindFontDef\n"));
1042
1043 for (i = 0; i < list->count; i++) {
1044 HPDF_FontDef def = (HPDF_FontDef)HPDF_List_ItemAt (list, i);
1045
1046 if (HPDF_StrCmp (font_name, def->base_font) == 0) {
1047 if (def->type == HPDF_FONTDEF_TYPE_UNINITIALIZED) {
1048 if (!def->init_fn ||
1049 def->init_fn (def) != HPDF_OK)
1050 return NULL;
1051 }
1052
1053 return def;
1054 }
1055 }
1056
1057 return NULL;
1058}
1059
1060
1061HPDF_STATUS
1062HPDF_Doc_RegisterFontDef (HPDF_Doc pdf,
1063 HPDF_FontDef fontdef)
1064{
1065 HPDF_STATUS ret;
1066
1067 HPDF_PTRACE ((" HPDF_Doc_RegisterFontDef\n"));
1068
1069 if (!fontdef)
1070 return HPDF_SetError (&pdf->error, HPDF_INVALID_OBJECT, 0);
1071
1072 if (HPDF_Doc_FindFontDef (pdf, fontdef->base_font) != NULL) {
1073 HPDF_FontDef_Free (fontdef);
1074 return HPDF_SetError (&pdf->error, HPDF_DUPLICATE_REGISTRATION, 0);
1075 }
1076
1077 if ((ret = HPDF_List_Add (pdf->fontdef_list, fontdef)) != HPDF_OK) {
1078 HPDF_FontDef_Free (fontdef);
1079 return HPDF_SetError (&pdf->error, ret, 0);
1080 }
1081
1082 return HPDF_OK;
1083}
1084
1085
1086
1087HPDF_FontDef
1088HPDF_GetFontDef (HPDF_Doc pdf,
1089 const char *font_name)
1090{
1091 HPDF_STATUS ret;
1092 HPDF_FontDef def;
1093
1094 HPDF_PTRACE ((" HPDF_GetFontDef\n"));
1095
1096 if (!HPDF_HasDoc (pdf))
1097 return NULL;
1098
1099 def = HPDF_Doc_FindFontDef (pdf, font_name);
1100
1101 if (!def) {
1102 def = HPDF_Base14FontDef_New (pdf->mmgr, font_name);
1103
1104 if (!def)
1105 return NULL;
1106
1107 if ((ret = HPDF_List_Add (pdf->fontdef_list, def)) != HPDF_OK) {
1108 HPDF_FontDef_Free (def);
1109 HPDF_RaiseError (&pdf->error, ret, 0);
1110 def = NULL;
1111 }
1112 }
1113
1114 return def;
1115}
1116
1117
1118/*----- encoder handling ----------------------------------------------------*/
1119
1120
1121HPDF_Encoder
1122HPDF_Doc_FindEncoder (HPDF_Doc pdf,
1123 const char *encoding_name)
1124{
1125 HPDF_List list = pdf->encoder_list;
1126 HPDF_UINT i;
1127
1128 HPDF_PTRACE ((" HPDF_Doc_FindEncoder\n"));
1129
1130 for (i = 0; i < list->count; i++) {
1131 HPDF_Encoder encoder = (HPDF_Encoder)HPDF_List_ItemAt (list, i);
1132
1133 if (HPDF_StrCmp (encoding_name, encoder->name) == 0) {
1134
1135 /* if encoder is uninitialize, call init_fn() */
1136 if (encoder->type == HPDF_ENCODER_TYPE_UNINITIALIZED) {
1137 if (!encoder->init_fn ||
1138 encoder->init_fn (encoder) != HPDF_OK)
1139 return NULL;
1140 }
1141
1142 return encoder;
1143 }
1144 }
1145
1146 return NULL;
1147}
1148
1149
1150
1151HPDF_STATUS
1152HPDF_Doc_RegisterEncoder (HPDF_Doc pdf,
1153 HPDF_Encoder encoder)
1154{
1155 HPDF_STATUS ret;
1156
1157 if (!encoder)
1158 return HPDF_SetError (&pdf->error, HPDF_INVALID_OBJECT, 0);
1159
1160 if (HPDF_Doc_FindEncoder (pdf, encoder->name) != NULL) {
1161 HPDF_Encoder_Free (encoder);
1162 return HPDF_SetError (&pdf->error, HPDF_DUPLICATE_REGISTRATION, 0);
1163 }
1164
1165 if ((ret = HPDF_List_Add (pdf->encoder_list, encoder)) != HPDF_OK) {
1166 HPDF_Encoder_Free (encoder);
1167 return HPDF_SetError (&pdf->error, ret, 0);
1168 }
1169
1170 return HPDF_OK;
1171}
1172
1173
1174HPDF_EXPORT(HPDF_Encoder)
1175HPDF_GetEncoder (HPDF_Doc pdf,
1176 const char *encoding_name)
1177{
1178 HPDF_Encoder encoder;
1179 HPDF_STATUS ret;
1180
1181 HPDF_PTRACE ((" HPDF_GetEncoder\n"));
1182
1183 if (!HPDF_HasDoc (pdf))
1184 return NULL;
1185
1186 encoder = HPDF_Doc_FindEncoder (pdf, encoding_name);
1187
1188 if (!encoder) {
1189 encoder = HPDF_BasicEncoder_New (pdf->mmgr, encoding_name);
1190
1191 if (!encoder) {
1192 HPDF_CheckError (&pdf->error);
1193 return NULL;
1194 }
1195
1196 if ((ret = HPDF_List_Add (pdf->encoder_list, encoder)) != HPDF_OK) {
1197 HPDF_Encoder_Free (encoder);
1198 HPDF_RaiseError (&pdf->error, ret, 0);
1199 return NULL;
1200 }
1201 }
1202
1203 return encoder;
1204}
1205
1206
1207HPDF_EXPORT(HPDF_Encoder)
1208HPDF_GetCurrentEncoder (HPDF_Doc pdf)
1209{
1210 if (!HPDF_HasDoc (pdf))
1211 return NULL;
1212
1213 return pdf->cur_encoder;
1214}
1215
1216
1217HPDF_EXPORT(HPDF_STATUS)
1218HPDF_SetCurrentEncoder (HPDF_Doc pdf,
1219 const char *encoding_name)
1220{
1221 HPDF_Encoder encoder;
1222
1223 if (!HPDF_HasDoc (pdf))
1224 return HPDF_GetError (pdf);
1225
1226 encoder = HPDF_GetEncoder (pdf, encoding_name);
1227
1228 if (!encoder)
1229 return HPDF_GetError (pdf);
1230
1231 pdf->cur_encoder = encoder;
1232
1233 return HPDF_OK;
1234}
1235
1236
1237static void
1238FreeEncoderList (HPDF_Doc pdf)
1239{
1240 HPDF_List list = pdf->encoder_list;
1241 HPDF_UINT i;
1242
1243 HPDF_PTRACE ((" FreeEncoderList\n"));
1244
1245 for (i = 0; i < list->count; i++) {
1246 HPDF_Encoder encoder = (HPDF_Encoder)HPDF_List_ItemAt (list, i);
1247
1248 HPDF_Encoder_Free (encoder);
1249 }
1250
1251 HPDF_List_Free (list);
1252
1253 pdf->encoder_list = NULL;
1254}
1255
1256
1257/*----- font handling -------------------------------------------------------*/
1258
1259
1260HPDF_Font
1261HPDF_Doc_FindFont (HPDF_Doc pdf,
1262 const char *font_name,
1263 const char *encoding_name)
1264{
1265 HPDF_UINT i;
1266 HPDF_Font font;
1267
1268 HPDF_PTRACE ((" HPDF_Doc_FindFont\n"));
1269
1270 for (i = 0; i < pdf->font_mgr->count; i++) {
1271 HPDF_FontAttr attr;
1272
1273 font = (HPDF_Font)HPDF_List_ItemAt (pdf->font_mgr, i);
1274 attr = (HPDF_FontAttr) font->attr;
1275
1276 if (HPDF_StrCmp (attr->fontdef->base_font, font_name) == 0 &&
1277 HPDF_StrCmp (attr->encoder->name, encoding_name) == 0)
1278 return font;
1279 }
1280
1281 return NULL;
1282}
1283
1284
1285HPDF_EXPORT(HPDF_Font)
1286HPDF_GetFont (HPDF_Doc pdf,
1287 const char *font_name,
1288 const char *encoding_name)
1289{
1290 HPDF_FontDef fontdef = NULL;
1291 HPDF_Encoder encoder = NULL;
1292 HPDF_Font font;
1293
1294 HPDF_PTRACE ((" HPDF_GetFont\n"));
1295
1296 if (!HPDF_HasDoc (pdf))
1297 return NULL;
1298
1299 if (!font_name) {
1300 HPDF_RaiseError (&pdf->error, HPDF_INVALID_FONT_NAME, 0);
1301 return NULL;
1302 }
1303
1304 /* if encoding-name is not specified, find default-encoding of fontdef
1305 */
1306 if (!encoding_name) {
1307 fontdef = HPDF_GetFontDef (pdf, font_name);
1308
1309 if (fontdef) {
1310 HPDF_Type1FontDefAttr attr = (HPDF_Type1FontDefAttr)fontdef->attr;
1311
1312 if (fontdef->type == HPDF_FONTDEF_TYPE_TYPE1 &&
1313 HPDF_StrCmp (attr->encoding_scheme,
1314 HPDF_ENCODING_FONT_SPECIFIC) == 0)
1315 encoder = HPDF_GetEncoder (pdf, HPDF_ENCODING_FONT_SPECIFIC);
1316 else
1317 encoder = HPDF_GetEncoder (pdf, HPDF_ENCODING_STANDARD);
1318 } else {
1319 HPDF_CheckError (&pdf->error);
1320 return NULL;
1321 }
1322
1323 if (!encoder) {
1324 HPDF_CheckError (&pdf->error);
1325 return NULL;
1326 }
1327
1328 font = HPDF_Doc_FindFont (pdf, font_name, encoder->name);
1329 } else {
1330 font = HPDF_Doc_FindFont (pdf, font_name, encoding_name);
1331 }
1332
1333 if (font)
1334 return font;
1335
1336 if (!fontdef) {
1337 fontdef = HPDF_GetFontDef (pdf, font_name);
1338
1339 if (!fontdef) {
1340 HPDF_CheckError (&pdf->error);
1341 return NULL;
1342 }
1343 }
1344
1345 if (!encoder) {
1346 encoder = HPDF_GetEncoder (pdf, encoding_name);
1347
1348 if (!encoder)
1349 return NULL;
1350 }
1351
1352 switch (fontdef->type) {
1353 case HPDF_FONTDEF_TYPE_TYPE1:
1354 font = HPDF_Type1Font_New (pdf->mmgr, fontdef, encoder, pdf->xref);
1355
1356 if (font)
1357 HPDF_List_Add (pdf->font_mgr, font);
1358
1359 break;
1360 case HPDF_FONTDEF_TYPE_TRUETYPE:
1361 if (encoder->type == HPDF_ENCODER_TYPE_DOUBLE_BYTE)
1362 font = HPDF_Type0Font_New (pdf->mmgr, fontdef, encoder,
1363 pdf->xref);
1364 else
1365 font = HPDF_TTFont_New (pdf->mmgr, fontdef, encoder, pdf->xref);
1366
1367 if (font)
1368 HPDF_List_Add (pdf->font_mgr, font);
1369
1370 break;
1371 case HPDF_FONTDEF_TYPE_CID:
1372 font = HPDF_Type0Font_New (pdf->mmgr, fontdef, encoder, pdf->xref);
1373
1374 if (font)
1375 HPDF_List_Add (pdf->font_mgr, font);
1376
1377 break;
1378 default:
1379 HPDF_RaiseError (&pdf->error, HPDF_UNSUPPORTED_FONT_TYPE, 0);
1380 return NULL;
1381 }
1382
1383 if (!font)
1384 HPDF_CheckError (&pdf->error);
1385
1386 if (font && (pdf->compression_mode & HPDF_COMP_METADATA))
1387 font->filter = HPDF_STREAM_FILTER_FLATE_DECODE;
1388
1389 return font;
1390}
1391
1392
1393HPDF_EXPORT(const char*)
1394HPDF_LoadType1FontFromFile (HPDF_Doc pdf,
1395 const char *afm_file_name,
1396 const char *data_file_name)
1397{
1398 HPDF_Stream afm;
1399 HPDF_Stream pfm = NULL;
1400 const char *ret;
1401
1402 HPDF_PTRACE ((" HPDF_LoadType1FontFromFile\n"));
1403
1404 if (!HPDF_HasDoc (pdf))
1405 return NULL;
1406
1407 /* create file stream */
1408 afm = HPDF_FileReader_New (pdf->mmgr, afm_file_name);
1409
1410 if (data_file_name)
1411 pfm = HPDF_FileReader_New (pdf->mmgr, data_file_name);
1412
1413 if (HPDF_Stream_Validate (afm) &&
1414 (!data_file_name || HPDF_Stream_Validate (pfm))) {
1415
1416 ret = LoadType1FontFromStream (pdf, afm, pfm);
1417 } else
1418 ret = NULL;
1419
1420 /* destroy file stream */
1421 if (afm)
1422 HPDF_Stream_Free (afm);
1423
1424 if (pfm)
1425 HPDF_Stream_Free (pfm);
1426
1427 if (!ret)
1428 HPDF_CheckError (&pdf->error);
1429
1430 return ret;
1431}
1432
1433
1434static const char*
1435LoadType1FontFromStream (HPDF_Doc pdf,
1436 HPDF_Stream afmdata,
1437 HPDF_Stream pfmdata)
1438{
1439 HPDF_FontDef def;
1440
1441 HPDF_PTRACE ((" HPDF_LoadType1FontFromStream\n"));
1442
1443 if (!HPDF_HasDoc (pdf))
1444 return NULL;
1445
1446 def = HPDF_Type1FontDef_Load (pdf->mmgr, afmdata, pfmdata);
1447 if (def) {
1448 HPDF_FontDef tmpdef = HPDF_Doc_FindFontDef (pdf, def->base_font);
1449 if (tmpdef) {
1450 HPDF_FontDef_Free (def);
1451 HPDF_SetError (&pdf->error, HPDF_FONT_EXISTS, 0);
1452 return NULL;
1453 }
1454
1455 if (HPDF_List_Add (pdf->fontdef_list, def) != HPDF_OK) {
1456 HPDF_FontDef_Free (def);
1457 return NULL;
1458 }
1459 return def->base_font;
1460 }
1461 return NULL;
1462}
1463
1464HPDF_EXPORT(HPDF_FontDef)
1465HPDF_GetTTFontDefFromFile (HPDF_Doc pdf,
1466 const char *file_name,
1467 HPDF_BOOL embedding)
1468{
1469 HPDF_Stream font_data;
1470 HPDF_FontDef def;
1471
1472 HPDF_PTRACE ((" HPDF_GetTTFontDefFromFile\n"));
1473
1474 /* create file stream */
1475 font_data = HPDF_FileReader_New (pdf->mmgr, file_name);
1476
1477 if (HPDF_Stream_Validate (font_data)) {
1478 def = HPDF_TTFontDef_Load (pdf->mmgr, font_data, embedding);
1479 } else {
1480 HPDF_CheckError (&pdf->error);
1481 return NULL;
1482 }
1483
1484 return def;
1485}
1486
1487HPDF_EXPORT(const char*)
1488HPDF_LoadTTFontFromFile (HPDF_Doc pdf,
1489 const char *file_name,
1490 HPDF_BOOL embedding)
1491{
1492 HPDF_Stream font_data;
1493 const char *ret;
1494
1495 HPDF_PTRACE ((" HPDF_LoadTTFontFromFile\n"));
1496
1497 if (!HPDF_HasDoc (pdf))
1498 return NULL;
1499
1500 /* create file stream */
1501 font_data = HPDF_FileReader_New (pdf->mmgr, file_name);
1502
1503 if (HPDF_Stream_Validate (font_data)) {
1504 ret = LoadTTFontFromStream (pdf, font_data, embedding, file_name);
1505 } else
1506 ret = NULL;
1507
1508 if (!ret)
1509 HPDF_CheckError (&pdf->error);
1510
1511 return ret;
1512}
1513
1514
1515static const char*
1516LoadTTFontFromStream (HPDF_Doc pdf,
1517 HPDF_Stream font_data,
1518 HPDF_BOOL embedding,
1519 const char *file_name)
1520{
1521 HPDF_FontDef def;
1522
1523 HPDF_PTRACE ((" HPDF_LoadTTFontFromStream\n"));
1524 HPDF_UNUSED (file_name);
1525
1526 def = HPDF_TTFontDef_Load (pdf->mmgr, font_data, embedding);
1527 if (def) {
1528 HPDF_FontDef tmpdef = HPDF_Doc_FindFontDef (pdf, def->base_font);
1529 if (tmpdef) {
1530 HPDF_FontDef_Free (def);
1531 return tmpdef->base_font;
1532 }
1533
1534 if (HPDF_List_Add (pdf->fontdef_list, def) != HPDF_OK) {
1535 HPDF_FontDef_Free (def);
1536 return NULL;
1537 }
1538 } else
1539 return NULL;
1540
1541 if (embedding) {
1542 if (pdf->ttfont_tag[0] == 0) {
1543 HPDF_MemCpy (pdf->ttfont_tag, (HPDF_BYTE *)"HPDFAA", 6);
1544 } else {
1545 HPDF_INT i;
1546
1547 for (i = 5; i >= 0; i--) {
1548 pdf->ttfont_tag[i] += 1;
1549 if (pdf->ttfont_tag[i] > 'Z')
1550 pdf->ttfont_tag[i] = 'A';
1551 else
1552 break;
1553 }
1554 }
1555
1556 HPDF_TTFontDef_SetTagName (def, (char *)pdf->ttfont_tag);
1557 }
1558
1559 return def->base_font;
1560}
1561
1562
1563HPDF_EXPORT(const char*)
1564HPDF_LoadTTFontFromFile2 (HPDF_Doc pdf,
1565 const char *file_name,
1566 HPDF_UINT index,
1567 HPDF_BOOL embedding)
1568{
1569 HPDF_Stream font_data;
1570 const char *ret;
1571
1572 HPDF_PTRACE ((" HPDF_LoadTTFontFromFile2\n"));
1573
1574 if (!HPDF_HasDoc (pdf))
1575 return NULL;
1576
1577 /* create file stream */
1578 font_data = HPDF_FileReader_New (pdf->mmgr, file_name);
1579
1580 if (HPDF_Stream_Validate (font_data)) {
1581 ret = LoadTTFontFromStream2 (pdf, font_data, index, embedding, file_name);
1582 } else
1583 ret = NULL;
1584
1585 if (!ret)
1586 HPDF_CheckError (&pdf->error);
1587
1588 return ret;
1589}
1590
1591
1592static const char*
1593LoadTTFontFromStream2 (HPDF_Doc pdf,
1594 HPDF_Stream font_data,
1595 HPDF_UINT index,
1596 HPDF_BOOL embedding,
1597 const char *file_name)
1598{
1599 HPDF_FontDef def;
1600
1601 HPDF_PTRACE ((" HPDF_LoadTTFontFromStream2\n"));
1602 HPDF_UNUSED (file_name);
1603
1604 def = HPDF_TTFontDef_Load2 (pdf->mmgr, font_data, index, embedding);
1605 if (def) {
1606 HPDF_FontDef tmpdef = HPDF_Doc_FindFontDef (pdf, def->base_font);
1607 if (tmpdef) {
1608 HPDF_FontDef_Free (def);
1609 return tmpdef->base_font;
1610 }
1611
1612 if (HPDF_List_Add (pdf->fontdef_list, def) != HPDF_OK) {
1613 HPDF_FontDef_Free (def);
1614 return NULL;
1615 }
1616 } else
1617 return NULL;
1618
1619 if (embedding) {
1620 if (pdf->ttfont_tag[0] == 0) {
1621 HPDF_MemCpy (pdf->ttfont_tag, (HPDF_BYTE *)"HPDFAA", 6);
1622 } else {
1623 HPDF_INT i;
1624
1625 for (i = 5; i >= 0; i--) {
1626 pdf->ttfont_tag[i] += 1;
1627 if (pdf->ttfont_tag[i] > 'Z')
1628 pdf->ttfont_tag[i] = 'A';
1629 else
1630 break;
1631 }
1632 }
1633
1634 HPDF_TTFontDef_SetTagName (def, (char *)pdf->ttfont_tag);
1635 }
1636
1637 return def->base_font;
1638}
1639
1640
1641HPDF_EXPORT(HPDF_Image)
1642HPDF_LoadRawImageFromFile (HPDF_Doc pdf,
1643 const char *filename,
1644 HPDF_UINT width,
1645 HPDF_UINT height,
1646 HPDF_ColorSpace color_space)
1647{
1648 HPDF_Stream imagedata;
1649 HPDF_Image image;
1650
1651 HPDF_PTRACE ((" HPDF_LoadRawImageFromFile\n"));
1652
1653 if (!HPDF_HasDoc (pdf))
1654 return NULL;
1655
1656 /* create file stream */
1657 imagedata = HPDF_FileReader_New (pdf->mmgr, filename);
1658
1659 if (HPDF_Stream_Validate (imagedata))
1660 image = HPDF_Image_LoadRawImage (pdf->mmgr, imagedata, pdf->xref, width,
1661 height, color_space);
1662 else
1663 image = NULL;
1664
1665 /* destroy file stream */
1666 HPDF_Stream_Free (imagedata);
1667
1668 if (!image)
1669 HPDF_CheckError (&pdf->error);
1670
1671 if (image && pdf->compression_mode & HPDF_COMP_IMAGE)
1672 image->filter = HPDF_STREAM_FILTER_FLATE_DECODE;
1673
1674 return image;
1675}
1676
1677
1678HPDF_EXPORT(HPDF_Image)
1679HPDF_LoadRawImageFromMem (HPDF_Doc pdf,
1680 const HPDF_BYTE *buf,
1681 HPDF_UINT width,
1682 HPDF_UINT height,
1683 HPDF_ColorSpace color_space,
1684 HPDF_UINT bits_per_component)
1685{
1686 HPDF_Image image;
1687
1688 HPDF_PTRACE ((" HPDF_LoadRawImageFromMem\n"));
1689
1690 if (!HPDF_HasDoc (pdf))
1691 return NULL;
1692
1693 /* Use directly HPDF_Image_LoadRaw1BitImageFromMem to save B/W images */
1694 if(color_space == HPDF_CS_DEVICE_GRAY && bits_per_component == 1) {
1695 return HPDF_Image_LoadRaw1BitImageFromMem (pdf, buf, width, height, (width+7)/8, HPDF_TRUE, HPDF_TRUE);
1696 }
1697
1698 image = HPDF_Image_LoadRawImageFromMem (pdf->mmgr, buf, pdf->xref, width, height, color_space, bits_per_component);
1699
1700 if (!image)
1701 HPDF_CheckError (&pdf->error);
1702
1703 if (image && pdf->compression_mode & HPDF_COMP_IMAGE) {
1704 image->filter = HPDF_STREAM_FILTER_FLATE_DECODE;
1705 }
1706
1707 return image;
1708}
1709
1710
1711HPDF_EXPORT(HPDF_Image)
1712HPDF_LoadJpegImageFromFile (HPDF_Doc pdf,
1713 const char *filename)
1714{
1715 HPDF_Stream imagedata;
1716 HPDF_Image image;
1717
1718 HPDF_PTRACE ((" HPDF_LoadJpegImageFromFile\n"));
1719
1720 if (!HPDF_HasDoc (pdf))
1721 return NULL;
1722
1723 /* create file stream */
1724 imagedata = HPDF_FileReader_New (pdf->mmgr, filename);
1725
1726 if (HPDF_Stream_Validate (imagedata))
1727 image = HPDF_Image_LoadJpegImage (pdf->mmgr, imagedata, pdf->xref);
1728 else
1729 image = NULL;
1730
1731 /* destroy file stream */
1732 HPDF_Stream_Free (imagedata);
1733
1734 if (!image)
1735 HPDF_CheckError (&pdf->error);
1736
1737 return image;
1738}
1739
1740HPDF_EXPORT(HPDF_Image)
1741HPDF_LoadJpegImageFromMem (HPDF_Doc pdf,
1742 const HPDF_BYTE *buffer,
1743 HPDF_UINT size)
1744{
1745 HPDF_Image image;
1746
1747 HPDF_PTRACE ((" HPDF_LoadJpegImageFromMem\n"));
1748
1749 if (!HPDF_HasDoc (pdf)) {
1750 return NULL;
1751 }
1752
1753 image = HPDF_Image_LoadJpegImageFromMem (pdf->mmgr, buffer, size , pdf->xref);
1754
1755 if (!image) {
1756 HPDF_CheckError (&pdf->error);
1757 }
1758
1759 return image;
1760}
1761
1762/*----- Catalog ------------------------------------------------------------*/
1763
1764HPDF_EXPORT(HPDF_PageLayout)
1765HPDF_GetPageLayout (HPDF_Doc pdf)
1766{
1767 HPDF_PTRACE ((" HPDF_GetPageLayout\n"));
1768
1769 if (!HPDF_HasDoc (pdf))
1770 return HPDF_PAGE_LAYOUT_SINGLE;
1771
1772 return HPDF_Catalog_GetPageLayout (pdf->catalog);
1773}
1774
1775
1776HPDF_EXPORT(HPDF_STATUS)
1777HPDF_SetPageLayout (HPDF_Doc pdf,
1778 HPDF_PageLayout layout)
1779{
1780 HPDF_STATUS ret;
1781
1782 HPDF_PTRACE ((" HPDF_GetPageLayout\n"));
1783
1784 if (!HPDF_HasDoc (pdf))
1785 return HPDF_INVALID_DOCUMENT;
1786
1787 if (layout < 0 || layout >= HPDF_PAGE_LAYOUT_EOF)
1788 return HPDF_RaiseError (&pdf->error, HPDF_PAGE_LAYOUT_OUT_OF_RANGE,
1789 (HPDF_STATUS)layout);
1790
1791 if ((layout == HPDF_PAGE_LAYOUT_TWO_PAGE_LEFT || layout == HPDF_PAGE_LAYOUT_TWO_PAGE_RIGHT) && pdf->pdf_version < HPDF_VER_15)
1792 pdf->pdf_version = HPDF_VER_15 ;
1793
1794 ret = HPDF_Catalog_SetPageLayout (pdf->catalog, layout);
1795 if (ret != HPDF_OK)
1796 HPDF_CheckError (&pdf->error);
1797
1798 return HPDF_OK;
1799}
1800
1801HPDF_EXPORT(HPDF_PageMode)
1802HPDF_GetPageMode (HPDF_Doc pdf)
1803{
1804 HPDF_PTRACE ((" HPDF_GetPageMode\n"));
1805
1806 if (!HPDF_HasDoc (pdf))
1807 return HPDF_PAGE_MODE_USE_NONE;
1808
1809 return HPDF_Catalog_GetPageMode (pdf->catalog);
1810}
1811
1812
1813HPDF_EXPORT(HPDF_STATUS)
1814HPDF_SetPageMode (HPDF_Doc pdf,
1815 HPDF_PageMode mode)
1816{
1817 HPDF_STATUS ret;
1818
1819 HPDF_PTRACE ((" HPDF_GetPageMode\n"));
1820
1821 if (!HPDF_HasDoc (pdf))
1822 return HPDF_INVALID_DOCUMENT;
1823
1824 if (mode < 0 || mode >= HPDF_PAGE_MODE_EOF)
1825 return HPDF_RaiseError (&pdf->error, HPDF_PAGE_MODE_OUT_OF_RANGE,
1826 (HPDF_STATUS)mode);
1827
1828 ret = HPDF_Catalog_SetPageMode (pdf->catalog, mode);
1829 if (ret != HPDF_OK)
1830 return HPDF_CheckError (&pdf->error);
1831
1832 return HPDF_OK;
1833}
1834
1835
1836HPDF_EXPORT(HPDF_STATUS)
1837HPDF_SetOpenAction (HPDF_Doc pdf,
1838 HPDF_Destination open_action)
1839{
1840 HPDF_STATUS ret;
1841
1842 HPDF_PTRACE ((" HPDF_SetOpenAction\n"));
1843
1844 if (!HPDF_HasDoc (pdf))
1845 return HPDF_INVALID_DOCUMENT;
1846
1847 if (open_action && !HPDF_Destination_Validate (open_action))
1848 return HPDF_RaiseError (&pdf->error, HPDF_INVALID_DESTINATION, 0);
1849
1850 ret = HPDF_Catalog_SetOpenAction (pdf->catalog, open_action);
1851 if (ret != HPDF_OK)
1852 return HPDF_CheckError (&pdf->error);
1853
1854 return HPDF_OK;
1855}
1856
1857
1858HPDF_EXPORT(HPDF_UINT)
1859HPDF_GetViewerPreference (HPDF_Doc pdf)
1860{
1861 HPDF_PTRACE ((" HPDF_Catalog_GetViewerPreference\n"));
1862
1863 if (!HPDF_HasDoc (pdf))
1864 return 0;
1865
1866 return HPDF_Catalog_GetViewerPreference (pdf->catalog);
1867}
1868
1869
1870HPDF_EXPORT(HPDF_STATUS)
1871HPDF_SetViewerPreference (HPDF_Doc pdf,
1872 HPDF_UINT value)
1873{
1874 HPDF_STATUS ret;
1875
1876 HPDF_PTRACE ((" HPDF_Catalog_SetViewerPreference\n"));
1877
1878 if (!HPDF_HasDoc (pdf))
1879 return HPDF_INVALID_DOCUMENT;
1880
1881 ret = HPDF_Catalog_SetViewerPreference (pdf->catalog, value);
1882 if (ret != HPDF_OK)
1883 return HPDF_CheckError (&pdf->error);
1884
1885 pdf->pdf_version = HPDF_VER_16;
1886
1887 return HPDF_OK;
1888}
1889
1890
1891HPDF_EXPORT(HPDF_STATUS)
1892HPDF_AddPageLabel (HPDF_Doc pdf,
1893 HPDF_UINT page_num,
1894 HPDF_PageNumStyle style,
1895 HPDF_UINT first_page,
1896 const char *prefix)
1897{
1898 HPDF_Dict page_label;
1899 HPDF_STATUS ret;
1900
1901 HPDF_PTRACE ((" HPDF_AddPageLabel\n"));
1902
1903 if (!HPDF_HasDoc (pdf))
1904 return HPDF_INVALID_DOCUMENT;
1905
1906 page_label = HPDF_PageLabel_New (pdf, style, first_page, prefix);
1907
1908 if (!page_label)
1909 return HPDF_CheckError (&pdf->error);
1910
1911 if (style < 0 || style >= HPDF_PAGE_NUM_STYLE_EOF)
1912 return HPDF_RaiseError (&pdf->error, HPDF_PAGE_NUM_STYLE_OUT_OF_RANGE,
1913 (HPDF_STATUS)style);
1914
1915 ret = HPDF_Catalog_AddPageLabel (pdf->catalog, page_num, page_label);
1916 if (ret != HPDF_OK)
1917 return HPDF_CheckError (&pdf->error);
1918
1919 return HPDF_OK;
1920}
1921
1922
1923HPDF_EXPORT(HPDF_EmbeddedFile)
1924HPDF_AttachFile (HPDF_Doc pdf,
1925 const char *file)
1926{
1927 HPDF_NameDict names;
1928 HPDF_NameTree ntree;
1929 HPDF_EmbeddedFile efile;
1930 HPDF_String name;
1931 HPDF_STATUS ret = HPDF_OK;
1932
1933 HPDF_PTRACE ((" HPDF_AttachFile\n"));
1934
1935 if (!HPDF_HasDoc (pdf))
1936 return NULL;
1937
1938 names = HPDF_Catalog_GetNames (pdf->catalog);
1939 if (!names) {
1940 names = HPDF_NameDict_New (pdf->mmgr, pdf->xref);
1941 if (!names)
1942 return NULL;
1943
1944 ret = HPDF_Catalog_SetNames (pdf->catalog, names);
1945 if (ret != HPDF_OK)
1946 return NULL;
1947 }
1948
1949 ntree = HPDF_NameDict_GetNameTree (names, HPDF_NAME_EMBEDDED_FILES);
1950 if (!ntree) {
1951 ntree = HPDF_NameTree_New (pdf->mmgr, pdf->xref);
1952 if (!ntree)
1953 return NULL;
1954
1955 ret = HPDF_NameDict_SetNameTree (names, HPDF_NAME_EMBEDDED_FILES, ntree);
1956 if (ret != HPDF_OK)
1957 return NULL;
1958 }
1959
1960 efile = HPDF_EmbeddedFile_New (pdf->mmgr, pdf->xref, file);
1961 if (!efile)
1962 return NULL;
1963
1964 name = HPDF_String_New (pdf->mmgr, file, NULL);
1965 if (!name)
1966 return NULL;
1967
1968 ret += HPDF_NameTree_Add (ntree, name, efile);
1969 if (ret != HPDF_OK)
1970 return NULL;
1971
1972 return efile;
1973}
1974
1975/*----- Info ---------------------------------------------------------------*/
1976
1977static HPDF_Dict
1978GetInfo (HPDF_Doc pdf)
1979{
1980 if (!HPDF_HasDoc (pdf))
1981 return NULL;
1982
1983 if (!pdf->info) {
1984 pdf->info = HPDF_Dict_New (pdf->mmgr);
1985
1986 if (!pdf->info || HPDF_Xref_Add (pdf->xref, pdf->info) != HPDF_OK)
1987 pdf->info = NULL;
1988 }
1989
1990 return pdf->info;
1991}
1992
1993
1994HPDF_EXPORT(HPDF_STATUS)
1995HPDF_SetInfoAttr (HPDF_Doc pdf,
1996 HPDF_InfoType type,
1997 const char *value)
1998{
1999 HPDF_STATUS ret;
2000 HPDF_Dict info = GetInfo (pdf);
2001
2002 HPDF_PTRACE((" HPDF_SetInfoAttr\n"));
2003
2004 if (!info)
2005 return HPDF_CheckError (&pdf->error);
2006
2007 ret = HPDF_Info_SetInfoAttr (info, type, value, pdf->cur_encoder);
2008 if (ret != HPDF_OK)
2009 return HPDF_CheckError (&pdf->error);
2010
2011 return ret;
2012}
2013
2014
2015HPDF_EXPORT(const char*)
2016HPDF_GetInfoAttr (HPDF_Doc pdf,
2017 HPDF_InfoType type)
2018{
2019 const char *ret = NULL;
2020 HPDF_Dict info = GetInfo (pdf);
2021
2022 HPDF_PTRACE((" HPDF_GetInfoAttr\n"));
2023
2024 if (info)
2025 ret = HPDF_Info_GetInfoAttr (info, type);
2026 else
2027 HPDF_CheckError (&pdf->error);
2028
2029 return ret;
2030}
2031
2032
2033HPDF_EXPORT(HPDF_STATUS)
2034HPDF_SetInfoDateAttr (HPDF_Doc pdf,
2035 HPDF_InfoType type,
2036 HPDF_Date value)
2037{
2038 HPDF_STATUS ret;
2039 HPDF_Dict info = GetInfo (pdf);
2040
2041 HPDF_PTRACE((" HPDF_SetInfoDateAttr\n"));
2042
2043 if (!info)
2044 return HPDF_CheckError (&pdf->error);
2045
2046 ret = HPDF_Info_SetInfoDateAttr (info, type, value);
2047 if (ret != HPDF_OK)
2048 return HPDF_CheckError (&pdf->error);
2049
2050 return ret;
2051}
2052
2053
2054HPDF_EXPORT(HPDF_Outline)
2055HPDF_CreateOutline (HPDF_Doc pdf,
2056 HPDF_Outline parent,
2057 const char *title,
2058 HPDF_Encoder encoder)
2059{
2060 HPDF_Outline outline;
2061
2062 if (!HPDF_HasDoc (pdf))
2063 return NULL;
2064
2065 if (!parent) {
2066 if (pdf->outlines) {
2067 parent = pdf->outlines;
2068 } else {
2069 pdf->outlines = HPDF_OutlineRoot_New (pdf->mmgr, pdf->xref);
2070
2071 if (pdf->outlines) {
2072 HPDF_STATUS ret = HPDF_Dict_Add (pdf->catalog, "Outlines",
2073 pdf->outlines);
2074 if (ret != HPDF_OK) {
2075 HPDF_CheckError (&pdf->error);
2076 pdf->outlines = NULL;
2077 return NULL;
2078 }
2079
2080 parent = pdf->outlines;
2081 } else {
2082 HPDF_CheckError (&pdf->error);
2083 return NULL;
2084 }
2085 }
2086 }
2087
2088 if (!HPDF_Outline_Validate (parent) || pdf->mmgr != parent->mmgr) {
2089 HPDF_RaiseError (&pdf->error, HPDF_INVALID_OUTLINE, 0);
2090 return NULL;
2091 }
2092
2093 outline = HPDF_Outline_New (pdf->mmgr, parent, title, encoder, pdf->xref);
2094 if (!outline)
2095 HPDF_CheckError (&pdf->error);
2096
2097 return outline;
2098}
2099
2100
2101HPDF_EXPORT(HPDF_ExtGState)
2102HPDF_CreateExtGState (HPDF_Doc pdf)
2103{
2104 HPDF_ExtGState ext_gstate;
2105
2106 if (!HPDF_HasDoc (pdf))
2107 return NULL;
2108
2109 pdf->pdf_version = HPDF_VER_14;
2110
2111 ext_gstate = HPDF_ExtGState_New (pdf->mmgr, pdf->xref);
2112 if (!ext_gstate)
2113 HPDF_CheckError (&pdf->error);
2114
2115 return ext_gstate;
2116}
2117
2118
2119HPDF_EXPORT(HPDF_STATUS)
2120HPDF_SetCompressionMode (HPDF_Doc pdf,
2121 HPDF_UINT mode)
2122{
2123 if (!HPDF_Doc_Validate (pdf))
2124 return HPDF_INVALID_DOCUMENT;
2125
2126 if (mode != (mode & HPDF_COMP_MASK))
2127 return HPDF_RaiseError (&pdf->error, HPDF_INVALID_COMPRESSION_MODE, 0);
2128
2129#ifndef LIBHPDF_HAVE_NOZLIB
2130 pdf->compression_mode = mode;
2131
2132 return HPDF_OK;
2133
2134#else /* LIBHPDF_HAVE_NOZLIB */
2135
2136 return HPDF_INVALID_COMPRESSION_MODE;
2137
2138#endif /* LIBHPDF_HAVE_NOZLIB */
2139}
2140
2141
2142HPDF_EXPORT(HPDF_STATUS)
2143HPDF_GetError (HPDF_Doc pdf)
2144{
2145 if (!HPDF_Doc_Validate (pdf))
2146 return HPDF_INVALID_DOCUMENT;
2147
2148 return HPDF_Error_GetCode (&pdf->error);
2149}
2150
2151
2152HPDF_EXPORT(HPDF_STATUS)
2153HPDF_GetErrorDetail (HPDF_Doc pdf)
2154{
2155 if (!HPDF_Doc_Validate (pdf))
2156 return HPDF_INVALID_DOCUMENT;
2157
2158 return HPDF_Error_GetDetailCode (&pdf->error);
2159}
2160
2161
2162HPDF_EXPORT(void)
2163HPDF_ResetError (HPDF_Doc pdf)
2164{
2165 if (!HPDF_Doc_Validate (pdf))
2166 return;
2167
2168 HPDF_Error_Reset (&pdf->error);
2169}
2170
2171/*
2172 * create an intententry
2173 */
2174HPDF_EXPORT(HPDF_OutputIntent)
2175HPDF_OutputIntent_New (HPDF_Doc pdf,
2176 const char* identifier,
2177 const char* condition,
2178 const char* registry,
2179 const char* info,
2180 HPDF_Array outputprofile)
2181{
2182 HPDF_OutputIntent intent;
2183 HPDF_STATUS ret = HPDF_OK;
2184
2185 HPDF_PTRACE((" HPDF_OutputIntent_New\n"));
2186
2187 if (!HPDF_HasDoc (pdf))
2188 return NULL;
2189
2190 intent = HPDF_Dict_New (pdf->mmgr);
2191 if (!intent)
2192 return NULL;
2193
2194 if (HPDF_Xref_Add (pdf->xref, intent) != HPDF_OK) {
2195 HPDF_Dict_Free(intent);
2196 return NULL;
2197 }
2198
2199 ret += HPDF_Dict_AddName (intent, "Type", "OutputIntent");
2200 ret += HPDF_Dict_AddName (intent, "S", "GTS_PDFX");
2201 ret += HPDF_Dict_Add (intent, "OutputConditionIdentifier", HPDF_String_New (pdf->mmgr, identifier, NULL));
2202 ret += HPDF_Dict_Add (intent, "OutputCondition", HPDF_String_New (pdf->mmgr, condition,NULL));
2203 ret += HPDF_Dict_Add (intent, "RegistryName", HPDF_String_New (pdf->mmgr, registry, NULL));
2204
2205 if (info != NULL) {
2206 ret += HPDF_Dict_Add (intent, "Info", HPDF_String_New (pdf->mmgr, info, NULL));
2207 }
2208
2209 /* add ICC base stream */
2210 if (outputprofile != NULL) {
2211 ret += HPDF_Dict_Add (intent, "DestOutputProfile ", outputprofile);
2212 }
2213
2214 if (ret != HPDF_OK) {
2215 HPDF_Dict_Free(intent);
2216 return NULL;
2217 }
2218
2219 return intent;
2220}
2221
2222HPDF_EXPORT(HPDF_STATUS)
2223HPDF_AddIntent(HPDF_Doc pdf,
2224 HPDF_OutputIntent intent)
2225{
2226 HPDF_Array intents;
2227 if (!HPDF_HasDoc (pdf))
2228 return HPDF_INVALID_DOCUMENT;
2229
2230 intents = HPDF_Dict_GetItem (pdf->catalog, "OutputIntents", HPDF_OCLASS_ARRAY);
2231 if (intents == NULL) {
2232 intents = HPDF_Array_New (pdf->mmgr);
2233 if (intents) {
2234 HPDF_STATUS ret = HPDF_Dict_Add (pdf->catalog, "OutputIntents", intents);
2235 if (ret != HPDF_OK) {
2236 HPDF_CheckError (&pdf->error);
2237 return HPDF_Error_GetDetailCode (&pdf->error);
2238 }
2239 }
2240 }
2241 HPDF_Array_Add(intents,intent);
2242 return HPDF_Error_GetDetailCode (&pdf->error);
2243}
2244
2245/* "Perceptual", "RelativeColorimetric", "Saturation", "AbsoluteColorimetric" */
2246HPDF_EXPORT(HPDF_OutputIntent)
2247HPDF_ICC_LoadIccFromMem (HPDF_Doc pdf,
2248 HPDF_MMgr mmgr,
2249 HPDF_Stream iccdata,
2250 HPDF_Xref xref,
2251 int numcomponent)
2252{
2253 HPDF_OutputIntent icc;
2254 HPDF_STATUS ret;
2255
2256 HPDF_PTRACE ((" HPDF_ICC_LoadIccFromMem\n"));
2257
2258 icc = HPDF_DictStream_New (mmgr, xref);
2259 if (!icc)
2260 return NULL;
2261
2262 HPDF_Dict_AddNumber (icc, "N", numcomponent);
2263 switch (numcomponent) {
2264 case 1 :
2265 HPDF_Dict_AddName (icc, "Alternate", "DeviceGray");
2266 break;
2267 case 3 :
2268 HPDF_Dict_AddName (icc, "Alternate", "DeviceRGB");
2269 break;
2270 case 4 :
2271 HPDF_Dict_AddName (icc, "Alternate", "DeviceCMYK");
2272 break;
2273 default : /* unsupported */
2274 HPDF_RaiseError (&pdf->error, HPDF_INVALID_ICC_COMPONENT_NUM, 0);
2275 HPDF_Dict_Free(icc);
2276 return NULL;
2277 }
2278
2279 for (;;) {
2280 HPDF_BYTE buf[HPDF_STREAM_BUF_SIZ];
2281 HPDF_UINT len = HPDF_STREAM_BUF_SIZ;
2282 ret = HPDF_Stream_Read (iccdata, buf, &len);
2283
2284 if (ret != HPDF_OK) {
2285 if (ret == HPDF_STREAM_EOF) {
2286 if (len > 0) {
2287 ret = HPDF_Stream_Write (icc->stream, buf, len);
2288 if (ret != HPDF_OK) {
2289 HPDF_Dict_Free(icc);
2290 return NULL;
2291 }
2292 }
2293 break;
2294 } else {
2295 HPDF_Dict_Free(icc);
2296 return NULL;
2297 }
2298 }
2299
2300 if (HPDF_Stream_Write (icc->stream, buf, len) != HPDF_OK) {
2301 HPDF_Dict_Free(icc);
2302 return NULL;
2303 }
2304 }
2305
2306 return icc;
2307}
2308
2309HPDF_EXPORT(HPDF_Array)
2310HPDF_AddColorspaceFromProfile (HPDF_Doc pdf,
2311 HPDF_Dict icc)
2312{
2313 HPDF_STATUS ret = HPDF_OK;
2314 HPDF_Array iccentry;
2315
2316 if (!HPDF_HasDoc (pdf))
2317 return NULL;
2318
2319 iccentry = HPDF_Array_New(pdf->mmgr);
2320 if (!iccentry)
2321 return NULL;
2322
2323 ret = HPDF_Array_AddName (iccentry, "ICCBased" );
2324 if (ret != HPDF_OK) {
2325 HPDF_Array_Free(iccentry);
2326 HPDF_CheckError (&pdf->error);
2327 return NULL;
2328 }
2329
2330 ret = HPDF_Array_Add (iccentry, icc );
2331 if (ret != HPDF_OK) {
2332 HPDF_Array_Free(iccentry);
2333 return NULL;
2334 }
2335 return iccentry;
2336}
2337
2338HPDF_EXPORT(HPDF_OutputIntent)
2339HPDF_LoadIccProfileFromFile (HPDF_Doc pdf,
2340 const char* icc_file_name,
2341 int numcomponent)
2342{
2343 HPDF_Stream iccdata;
2344 HPDF_OutputIntent iccentry;
2345
2346 HPDF_PTRACE ((" HPDF_LoadIccProfileFromFile\n"));
2347
2348 if (!HPDF_HasDoc (pdf))
2349 return NULL;
2350
2351 /* create file stream */
2352 iccdata = HPDF_FileReader_New (pdf->mmgr, icc_file_name);
2353
2354 if (HPDF_Stream_Validate (iccdata)) {
2355 iccentry = HPDF_ICC_LoadIccFromMem(pdf, pdf->mmgr, iccdata, pdf->xref, numcomponent);
2356 } else
2357 iccentry = NULL;
2358
2359 /* destroy file stream */
2360 if (iccdata)
2361 HPDF_Stream_Free (iccdata);
2362
2363 if (!iccentry)
2364 HPDF_CheckError (&pdf->error);
2365
2366 return iccentry;
2367}
2368
2369