1/*---------------------------------------------------------------------------*
2 |              PDFlib - A library for generating PDF on the fly             |
3 +---------------------------------------------------------------------------+
4 | Copyright (c) 1997-2004 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 14574 2005-10-29 16:27:43Z bonefish $
14 *
15 * PDFlib template routines
16 *
17 */
18
19#include "p_intern.h"
20#include "p_image.h"
21#include "p_font.h"
22
23/* Start a new template definition. */
24PDFLIB_API int PDFLIB_CALL
25PDF_begin_template(PDF *p, float width, float height)
26{
27    static const char fn[] = "PDF_begin_template";
28    pdf_image *image;
29    int im = -1;
30
31    if (!pdf_enter_api(p, fn, pdf_state_document, "(p[%p], %g, %g)",
32	(void *) p, width, height))
33    {
34        PDF_RETURN_HANDLE(p, im)
35    }
36
37    if (width <= 0)
38	pdc_error(p->pdc, PDC_E_ILLARG_POSITIVE, "width", 0, 0, 0);
39
40    if (height <= 0)
41	pdc_error(p->pdc, PDC_E_ILLARG_POSITIVE, "height", 0, 0, 0);
42
43    for (im = 0; im < p->images_capacity; im++)
44	if (!p->images[im].in_use)		/* found free slot */
45	    break;
46
47    if (im == p->images_capacity)
48	pdf_grow_images(p);
49
50    image		= &p->images[im];
51    image->in_use	= pdc_true;		/* mark slot as used */
52    image->no		= pdf_new_xobject(p, form_xobject, PDC_NEW_ID);
53    image->width	= width;
54    image->height	= height;
55
56    p->height		= height;
57    p->width		= width;
58    p->thumb_id		= PDC_BAD_ID;
59    PDF_PUSH_STATE(p, fn, pdf_state_template);
60    p->templ		= im;		/* remember the current template id */
61    p->next_content	= 0;
62    p->contents 	= c_page;
63    p->sl		= 0;
64
65    pdf_init_tstate(p);
66    pdf_init_gstate(p);
67    pdf_init_cstate(p);
68
69    pdc_begin_dict(p->out);				/* form xobject dict*/
70    pdc_puts(p->out, "/Type/XObject\n");
71    pdc_puts(p->out, "/Subtype/Form\n");
72
73    /* contrary to the PDF reference /FormType and /Matrix are required! */
74    pdc_printf(p->out, "/FormType 1\n");
75    pdc_printf(p->out, "/Matrix[1 0 0 1 0 0]\n");
76
77    p->res_id = pdc_alloc_id(p->out);
78    pdc_printf(p->out, "/Resources %ld 0 R\n", p->res_id);
79
80    pdc_printf(p->out, "/BBox[0 0 %f %f]\n", p->width, p->height);
81
82    p->length_id = pdc_alloc_id(p->out);
83    pdc_printf(p->out, "/Length %ld 0 R\n", p->length_id);
84
85    if (pdc_get_compresslevel(p->out))
86	pdc_puts(p->out, "/Filter/FlateDecode\n");
87
88    pdc_end_dict(p->out);				/* form xobject dict*/
89    pdc_begin_pdfstream(p->out);
90
91    p->next_content++;
92
93    /* top-down y-coordinates */
94    pdf_set_topdownsystem(p, height);
95
96    PDF_RETURN_HANDLE(p, im)
97}
98
99/* Finish the template definition. */
100PDFLIB_API void PDFLIB_CALL
101PDF_end_template(PDF *p)
102{
103    static const char fn[] = "PDF_end_template";
104
105    if (!pdf_enter_api(p, fn, pdf_state_template, "(p[%p])\n", (void *) p))
106	return;
107
108    /* check whether pdf__save() and pdf__restore() calls are balanced */
109    if (p->sl > 0)
110	pdc_error(p->pdc, PDF_E_GSTATE_UNMATCHEDSAVE, 0, 0, 0, 0);
111
112    pdf_end_text(p);
113    p->contents = c_none;
114
115    pdc_end_pdfstream(p->out);
116    pdc_end_obj(p->out);			/* form xobject */
117
118    pdc_put_pdfstreamlength(p->out, p->length_id);
119
120    pdc_begin_obj(p->out, p->res_id);		/* Resource object */
121    pdc_begin_dict(p->out);			/* Resource dict */
122
123    pdf_write_page_fonts(p);			/* Font resources */
124
125    pdf_write_page_colorspaces(p);		/* Color space resources */
126
127    pdf_write_page_pattern(p);			/* Pattern resources */
128
129    pdf_write_xobjects(p);			/* XObject resources */
130
131    pdf_write_page_extgstates(p);		/* ExtGState resources */
132
133    pdc_end_dict(p->out);			/* resource dict */
134    pdc_end_obj(p->out);			/* resource object */
135
136    PDF_POP_STATE(p, fn);
137
138    if (p->flush & pdf_flush_page)
139	pdc_flush_stream(p->out);
140}
141