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