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_object.c,v 1.56.2.3 2008/02/07 20:13:17 kurt Exp $
14  *
15  * PDFlib PDF object functions
16  *
17  */
18 
19 #define P_OBJECT_C
20 
21 #include "p_intern.h"
22 #include "p_image.h"
23 
24 
25 
26 static const pdc_keyconn pdf_scope_keylist[] =
27 {
28     {"object",       pdf_state_object},
29     {"document",     pdf_state_document},
30     {"page",         pdf_state_page},
31     {"pattern",      pdf_state_pattern},
32     {"template",     pdf_state_template},
33     {"path",         pdf_state_path},
34     {"font",         pdf_state_font},
35     {"glyph",        pdf_state_glyph},
36     {"glyphmetrics", pdf_state_glyphmetrics},
37     {"glyphignore",  pdf_state_glyphignore},
38     {"error",        pdf_state_error},
39     {NULL, 0}
40 };
41 
42 static pdc_error_info   pdf_errors[] =
43 {
44 #define         pdf_genInfo     1
45 #include        "p_generr.h"
46 };
47 
48 #define N_PDF_ERRORS    (sizeof pdf_errors / sizeof (pdc_error_info))
49 
50 const char *
pdf_current_scope(PDF * p)51 pdf_current_scope(PDF *p)
52 {
53     const char *scopename =
54         pdc_get_keyword(PDF_GET_STATE(p), pdf_scope_keylist);
55 
56     if (!scopename)
57         pdc_error(p->pdc, PDF_E_INT_BADSCOPE,
58             pdc_errprintf(p->pdc, " (0x%08X)", PDF_GET_STATE(p)), 0, 0, 0);
59 
60     return (char *) scopename;	/* be happy, compiler! */
61 }
62 
63 /* p may be NULL on the first call - we don't use it anyway */
64 static void *
default_malloc(PDF * p,size_t size,const char * caller)65 default_malloc(PDF *p, size_t size, const char *caller)
66 {
67     void *ret = malloc(size);
68 
69     (void) p;
70     (void) caller;
71 
72     return ret;
73 }
74 
75 static void *
default_realloc(PDF * p,void * mem,size_t size,const char * caller)76 default_realloc(PDF *p, void *mem, size_t size, const char *caller)
77 {
78     void *ret = realloc(mem, size);
79 
80     (void) p;
81     (void) caller;
82 
83     return ret;
84 }
85 
86 static void
default_free(PDF * p,void * mem)87 default_free(PDF *p, void *mem)
88 {
89     (void) p;
90 
91     free(mem);
92 }
93 
94 PDF *
pdf__new(void (* errorhandler)(PDF * p,int type,const char * msg),void * (* allocproc)(PDF * p,size_t size,const char * caller),void * (* reallocproc)(PDF * p,void * mem,size_t size,const char * caller),void (* freeproc)(PDF * p,void * mem),void * opaque)95 pdf__new(
96     void  (*errorhandler)(PDF *p, int type, const char *msg),
97     void* (*allocproc)(PDF *p, size_t size, const char *caller),
98     void* (*reallocproc)(PDF *p, void *mem, size_t size, const char *caller),
99     void  (*freeproc)(PDF *p, void *mem),
100     void   *opaque)
101 {
102     PDF *	p;
103     pdc_core *	pdc;
104 
105     /* If allocproc is NULL, all entries are supplied internally by PDFlib */
106     if (allocproc == NULL) {
107 	allocproc	= default_malloc;
108 	reallocproc	= default_realloc;
109 	freeproc	= default_free;
110     }
111 
112     p = (PDF *) (*allocproc) (NULL, sizeof(PDF), "PDF_new");
113 
114     if (p == NULL)
115 	return NULL;
116 
117     /*
118      * Guard against crashes when PDF_delete is called without any
119      * PDF_open_*() in between.
120      */
121     memset((void *)p, 0, (size_t) sizeof(PDF));
122 
123     /* these two are required by PDF_get_opaque() */
124     p->magic = PDC_MAGIC;
125     p->opaque = opaque;
126 
127     pdc = pdc_new_core(
128 	(pdc_error_fp) errorhandler,
129 	(pdc_alloc_fp) allocproc,
130 	(pdc_realloc_fp) reallocproc,
131 	(pdc_free_fp) freeproc, p,
132         PDFLIB_PRODUCTNAME,
133         PDFLIB_VERSIONSTRING);
134 
135     if (pdc == NULL)
136     {
137 	(*freeproc)(p, p);
138 	return NULL;
139     }
140 
141     pdc_register_errtab(pdc, PDC_ET_PDFLIB, pdf_errors, N_PDF_ERRORS);
142     fnt_register_errtab(pdc);
143 
144     PDC_TRY(pdc)
145     {
146         p->freeproc	= freeproc;
147         p->pdc		= pdc;
148         p->compatibility    = PDF_DEF_COMPATIBILITY;
149         p->errorpolicy      = errpol_legacy;
150 
151         p->userinfo         = NULL;
152         p->document         = NULL;
153 
154         p->errorhandler	= errorhandler;
155 
156         p->flush	    = pdc_flush_page;
157 
158         p->hypertextencoding= pdc_invalidenc;
159         p->hypertextformat  = pdc_auto;
160         p->hypertextcodepage= 0;
161         p->usercoordinates  = pdc_false;
162         p->usehyptxtenc     = pdc_false;
163 
164         p->currfo           = NULL;
165         p->curr_ppt         = NULL;
166 
167         p->glyphcheck = text_nocheck;
168         p->textformat       = pdc_auto;
169         p->in_text	    = pdc_false;
170 
171 
172         p->rendintent       = AutoIntent;
173         p->preserveoldpantonenames = pdc_false;
174         p->spotcolorlookup  = pdc_true;
175         p->ydirection       = 1;
176         p->names	    = NULL;
177         p->names_capacity   = 0;
178         p->xobjects     = NULL;
179         p->state_sp	= 0;
180         p->doc_pages    = NULL;
181 
182         p->actions = NULL;
183 
184 
185 
186 
187 
188         PDF_SET_STATE(p, pdf_state_object);
189 
190         /* all debug flags are cleared by default
191          * because of the above memset... */
192 
193         /* ...but warning messages for non-fatal errors should be set,
194          * as well as font warnings -- the client must explicitly disable these.
195          */
196         p->debug[(int) 'e'] = pdc_true;
197         p->debug[(int) 'F'] = pdc_true;
198         p->debug[(int) 'I'] = pdc_true;
199 
200         pdf_init_stringlists(p);
201         pdf_init_font_options(p, NULL);
202 
203         p->out = pdc_boot_output(p->pdc);
204 
205 
206     }
207     PDC_CATCH(pdc)
208     {
209         pdc_delete_core(pdc);
210         return (PDF *) 0;
211     }
212     return p;
213 } /* pdf__new */
214 
215 
216 /*
217  * PDF_delete must be called for cleanup in case of error,
218  * or when the client is done producing PDF.
219  * It should never be called more than once for a given PDF, although
220  * we try to guard against duplicated calls.
221  *
222  * Note: all pdf_cleanup_*() functions may safely be called multiple times.
223  */
224 
225 void
pdf__delete(PDF * p)226 pdf__delete(PDF *p)
227 {
228     /*
229      * Close the output stream, because it could be open
230      */
231     pdc_close_output(p->out);
232 
233     /*
234      * Clean up page-related stuff if necessary. Do not raise
235      * an error here since we may be called from the error handler.
236      */
237     pdf_cleanup_document(p);
238     pdf_cleanup_stringlists(p);
239     pdf_cleanup_font_curroptions(p);
240     pdc_cleanup_output(p->out, pdc_false);
241 
242 
243 
244 
245     if (p->out)
246     {
247 	pdc_free(p->pdc, p->out);
248         p->out = NULL;
249     }
250 
251     /* we never reach this point if (p->pdc == NULL).
252     */
253     pdc_delete_core(p->pdc);
254 
255     /* free the PDF structure and try to protect against duplicated calls */
256 
257     p->magic = 0L;		/* we don't reach this with the wrong magic */
258     (*p->freeproc)(p, (void *) p);
259 }
260 
261