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