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_template.c,v 1.82.2.11 2010/03/17 12:52:05 kurt Exp $
14  *
15  * PDFlib template routines
16  *
17  */
18 
19 #define P_TEMPLATE_C
20 
21 #include "p_intern.h"
22 #include "p_image.h"
23 
24 
25 int
pdf_embed_image(PDF * p,int im)26 pdf_embed_image(PDF *p, int im)
27 {
28     pdf_image *image = &p->images[im];
29     char optlist[PDC_GEN_BUFSIZE], *ol;
30     pdc_scalar width, height;
31     int templ;
32 
33     width = image->width;
34     height = fabs(image->height);
35 
36     /* create option list */
37     optlist[0] = 0;
38     ol = optlist;
39 
40 
41     if (image->iconname)
42         pdc_sprintf(p->pdc, pdc_false, ol, "iconname {%s}", image->iconname);
43 
44     /* create template */
45     templ = pdf__begin_template(p, width, height, optlist);
46 
47     /* fit image */
48     pdc_sprintf(p->pdc, pdc_false, optlist, "boxsize {%g %g} fitmethod meet",
49                 width, height);
50     pdf__fit_image(p, im, 0, 0, optlist);
51 
52     /* end template */
53     pdf__end_template(p);
54 
55     return templ;
56 }
57 
58 #define PDF_OPIOPT_FLAG PDC_OPT_UNSUPP
59 
60 #define PDF_METADATA_FLAG  PDC_OPT_UNSUPP
61 
62 #define PDF_LAYER_FLAG PDC_OPT_UNSUPP
63 
64 /* definitions of begin template options */
65 static const pdc_defopt pdf_begin_template_options[] =
66 {
67     {"topdown", pdc_booleanlist, PDC_OPT_NONE, 1, 1, 0.0, 0.0, NULL},
68 
69     {"transparencygroup", pdc_stringlist,  PDC_OPT_PDC_1_4, 1, 1,
70       1.0, PDF_MAX_NAMESTRING, NULL},
71 
72     {"OPI-1.3", pdc_stringlist, PDF_OPIOPT_FLAG, 1, 1, 0.0, 32000.0, NULL},
73 
74     {"OPI-2.0", pdc_stringlist, PDF_OPIOPT_FLAG | PDC_OPT_IGNOREIF1,
75       1, 1, 0.0, 32000.0, NULL},
76 
77     {"iconname", pdc_stringlist, 0, 1, 1, 1.0, PDF_MAX_NAMESTRING, NULL},
78 
79     {"metadata", pdc_stringlist, PDF_METADATA_FLAG, 1, 1,
80       0.0, PDC_INT_MAX, NULL},
81 
82     {"layer", pdc_layerhandle, PDF_LAYER_FLAG, 1, 1,
83       0.0, 0.0, NULL},
84 
85     PDF_ERRORPOLICY_OPTION
86 
87     PDC_OPT_TERMINATE
88 };
89 
90 /* Start a new template definition. */
91 int
pdf__begin_template(PDF * p,pdc_scalar width,pdc_scalar height,const char * optlist)92 pdf__begin_template(PDF *p, pdc_scalar width, pdc_scalar height,
93                     const char *optlist)
94 {
95     pdf_image *image;
96     pdc_resopt *resopts;
97     const char *keyword;
98     pdc_clientdata cdata;
99     pdc_bool topdown;
100     char *iconname = NULL;
101     pdc_bool verbose = pdc_true;
102     int im = -1;
103 
104     pdc_check_number_limits(p->pdc, "width", width,
105                             PDC_FLOAT_PREC, PDC_FLOAT_MAX);
106     pdc_check_number_limits(p->pdc, "height", height,
107                             PDC_FLOAT_PREC, PDC_FLOAT_MAX);
108 
109     for (im = 0; im < p->images_capacity; im++)
110 	if (!p->images[im].in_use)		/* found free slot */
111 	    break;
112 
113     if (im == p->images_capacity)
114 	pdf_grow_images(p);
115 
116     image = &p->images[im];
117     image->verbose = pdf_get_errorpolicy(p, NULL, image->verbose);
118     image->topdown_save = (p->ydirection == -1) ? pdc_true : pdc_false;
119     topdown = image->topdown_save;
120     image->in_use = pdc_true;                 /* mark slot as used */
121     image->tgroup.colorspace = color_none;
122     image->tgroup.isolated = pdc_false;
123     image->tgroup.knockout = pdc_false;
124 
125     /* parsing optlist */
126     pdf_set_clientdata(p, &cdata);
127     resopts = pdc_parse_optionlist(p->pdc, optlist, pdf_begin_template_options,
128                                    &cdata, pdc_true);
129 
130     /* save and check options */
131     if (optlist && *optlist)
132     {
133 	char **slist;
134 
135         image->verbose = pdf_get_errorpolicy(p, resopts, image->verbose);
136 
137         keyword = "topdown";
138         pdc_get_optvalues(keyword, resopts, &topdown, NULL);
139 
140 	if (pdc_get_optvalues("transparencygroup", resopts, NULL, &slist))
141         {
142             pdf_set_transgroup(p, slist[0], &image->tgroup);
143         }
144 
145         keyword = "iconname";
146         if (pdc_get_optvalues(keyword, resopts, NULL, NULL))
147             iconname = (char *) pdc_save_lastopt(resopts, PDC_OPT_SAVE1ELEM);
148 
149 
150 
151 
152         pdc_cleanup_optionlist(p->pdc, resopts);
153     }
154 
155     verbose = image->verbose;
156 
157 
158 
159     p->ydirection = topdown ? -1 : 1;
160     pdf_pg_suspend(p);
161     PDF_SET_STATE(p, pdf_state_template);
162 
163 
164 
165     /* form xobject */
166     image->no = pdf_new_xobject(p, form_xobject, PDC_NEW_ID);
167     image->width = width;
168     image->height = height;
169 
170     p->templ = im;		        /* remember the current template id */
171 
172     pdc_begin_dict(p->out);				/* form xobject dict*/
173     pdc_puts(p->out, "/Type/XObject\n");
174     pdc_puts(p->out, "/Subtype/Form\n");
175 
176     /* contrary to the PDF reference /FormType and /Matrix are required! */
177     pdc_printf(p->out, "/FormType 1\n");
178     pdc_printf(p->out, "/Matrix[1 0 0 1 0 0]\n");
179 
180     p->res_id = pdc_alloc_id(p->out);
181     pdc_objref(p->out, "/Resources", p->res_id);
182 
183     pdc_printf(p->out, "/BBox[0 0 %f %f]\n", width, height);
184 
185     if (image->tgroup.colorspace != color_none)
186 	pdf_write_transgroup(p, &image->tgroup);
187 
188 
189 
190 
191     p->length_id = pdc_alloc_id(p->out);
192     pdc_objref(p->out, "/Length", p->length_id);
193 
194     if (pdc_get_compresslevel(p->out))
195 	pdc_puts(p->out, "/Filter/FlateDecode\n");
196 
197     pdc_end_dict(p->out);				/* form xobject dict*/
198 
199     pdc_begin_pdfstream(p->out);
200 
201     /* top-down y-coordinates */
202     pdf_set_topdownsystem(p, height);
203 
204     /* set color differing from PDF default */
205     pdf_set_default_color(p, pdc_false);
206 
207     /* insert icon name */
208     if (iconname)
209     {
210         pdc_id obj_id = pdf_get_xobject(p, im);
211         pdf_insert_name(p, iconname, names_ap, obj_id);
212     }
213 
214     if (!p->pdc->smokerun)
215 	pdc_logg_cond(p->pdc, 1, trc_api, "[Begin template %d]\n", p->templ);
216 
217     return im;
218 }
219 
220 /* Finish the template definition. */
221 void
pdf__end_template(PDF * p)222 pdf__end_template(PDF *p)
223 {
224     pdf_image *image = &p->images[p->templ];
225 
226     /* check whether pdf__save() and pdf__restore() calls are balanced */
227     if (p->curr_ppt->sl > 0)
228         pdc_error(p->pdc, PDF_E_GSTATE_UNMATCHEDSAVE, 0, 0, 0, 0);
229 
230     pdf_end_text(p);
231     pdc_end_pdfstream(p->out);
232     pdc_end_obj(p->out);                        /* form xobject */
233 
234     pdc_put_pdfstreamlength(p->out, p->length_id);
235 
236     pdc_begin_obj(p->out, p->res_id);           /* Resource object */
237     pdc_begin_dict(p->out);                     /* Resource dict */
238 
239     pdf_write_page_fonts(p);                    /* Font resources */
240 
241     pdf_write_page_colorspaces(p);              /* Color space resources */
242 
243     pdf_write_page_pattern(p);                  /* Pattern resources */
244 
245     pdf_write_xobjects(p);                      /* XObject resources */
246 
247     pdf_write_page_extgstates(p);               /* ExtGState resources */
248 
249     pdc_end_dict(p->out);                       /* resource dict */
250     pdc_end_obj(p->out);                        /* resource object */
251 
252     pdf_pg_resume(p, -1);
253 
254     if (p->flush & pdc_flush_content)
255         pdc_flush_stream(p->out);
256 
257     p->ydirection = image->topdown_save ? -1 : 1;
258 
259     if (!p->pdc->smokerun)
260 	pdc_logg_cond(p->pdc, 1, trc_api, "[End template %d]\n", p->templ);
261 }
262 
263 
264