Thu, 20 Feb 2003 12:16:00 +0000
my own PDF routines to replace Panda.
eric@59 | 1 | #include <stdio.h> |
eric@59 | 2 | #include <stdlib.h> |
eric@59 | 3 | |
eric@59 | 4 | |
eric@59 | 5 | #include "libpdf.h" |
eric@59 | 6 | #include "libpdf_util.h" |
eric@59 | 7 | #include "libpdf_prim.h" |
eric@59 | 8 | #include "libpdf_private.h" |
eric@59 | 9 | |
eric@59 | 10 | |
eric@59 | 11 | static void pdf_set_info (pdf_file_handle pdf_file, char *key, char *val) |
eric@59 | 12 | { |
eric@59 | 13 | if (! pdf_file->info) |
eric@59 | 14 | pdf_file->info = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY)); |
eric@59 | 15 | |
eric@59 | 16 | pdf_set_dict_entry (pdf_file->info, key, pdf_new_string (val)); |
eric@59 | 17 | } |
eric@59 | 18 | |
eric@59 | 19 | |
eric@59 | 20 | void pdf_init (void) |
eric@59 | 21 | { |
eric@59 | 22 | } |
eric@59 | 23 | |
eric@59 | 24 | |
eric@59 | 25 | struct pdf_pages *pdf_new_pages (pdf_file_handle pdf_file) |
eric@59 | 26 | { |
eric@59 | 27 | struct pdf_pages *pages = pdf_calloc (sizeof (struct pdf_pages)); |
eric@59 | 28 | pages->kids = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_ARRAY)); |
eric@59 | 29 | pages->count = pdf_new_integer (0); |
eric@59 | 30 | pages->pages_dict = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY)); |
eric@59 | 31 | pdf_set_dict_entry (pages->pages_dict, "Type", pdf_new_name ("Pages")); |
eric@59 | 32 | pdf_set_dict_entry (pages->pages_dict, "Kids", pages->kids); |
eric@59 | 33 | pdf_set_dict_entry (pages->pages_dict, "Count", pages->count); |
eric@59 | 34 | return (pages); |
eric@59 | 35 | } |
eric@59 | 36 | |
eric@59 | 37 | |
eric@59 | 38 | pdf_file_handle pdf_create (char *filename) |
eric@59 | 39 | { |
eric@59 | 40 | pdf_file_handle pdf_file; |
eric@59 | 41 | |
eric@59 | 42 | pdf_file = pdf_calloc (sizeof (struct pdf_file)); |
eric@59 | 43 | |
eric@59 | 44 | pdf_file->f = fopen (filename, "wb"); |
eric@59 | 45 | if (! pdf_file->f) |
eric@59 | 46 | { |
eric@59 | 47 | pdf_fatal ("error opening output file\n"); |
eric@59 | 48 | } |
eric@59 | 49 | |
eric@59 | 50 | pdf_file->root = pdf_new_pages (pdf_file); |
eric@59 | 51 | |
eric@59 | 52 | pdf_file->catalog = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY)); |
eric@59 | 53 | pdf_set_dict_entry (pdf_file->catalog, "Type", pdf_new_name ("Catalog")); |
eric@59 | 54 | pdf_set_dict_entry (pdf_file->catalog, "Pages", pdf_file->root->pages_dict); |
eric@59 | 55 | /* Outlines dictionary will be created later if needed*/ |
eric@59 | 56 | pdf_set_dict_entry (pdf_file->catalog, "PageMode", pdf_new_name ("UseNone")); |
eric@59 | 57 | |
eric@59 | 58 | pdf_file->info = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY)); |
eric@59 | 59 | pdf_set_info (pdf_file, "Producer", "libpdf, Copyright 2003 Eric Smith <eric@brouhaha.com>"); |
eric@59 | 60 | |
eric@59 | 61 | pdf_file->trailer_dict = pdf_new_obj (PT_DICTIONARY); |
eric@59 | 62 | /* Size key will be added later */ |
eric@59 | 63 | pdf_set_dict_entry (pdf_file->trailer_dict, "Root", pdf_file->catalog); |
eric@59 | 64 | pdf_set_dict_entry (pdf_file->trailer_dict, "Info", pdf_file->info); |
eric@59 | 65 | |
eric@59 | 66 | /* write file header */ |
eric@59 | 67 | fprintf (pdf_file->f, "%%PDF-1.2\r\n"); |
eric@59 | 68 | |
eric@59 | 69 | return (pdf_file); |
eric@59 | 70 | } |
eric@59 | 71 | |
eric@59 | 72 | |
eric@59 | 73 | void pdf_close (pdf_file_handle pdf_file) |
eric@59 | 74 | { |
eric@59 | 75 | /* write body */ |
eric@59 | 76 | pdf_write_all_ind_obj (pdf_file); |
eric@59 | 77 | |
eric@59 | 78 | /* write cross reference table and get maximum object number */ |
eric@59 | 79 | pdf_set_dict_entry (pdf_file->trailer_dict, "Size", pdf_new_integer (pdf_write_xref (pdf_file))); |
eric@59 | 80 | |
eric@59 | 81 | /* write trailer */ |
eric@59 | 82 | fprintf (pdf_file->f, "trailer\r\n"); |
eric@59 | 83 | pdf_write_obj (pdf_file, pdf_file->trailer_dict); |
eric@59 | 84 | fprintf (pdf_file->f, "startxref\r\n"); |
eric@59 | 85 | fprintf (pdf_file->f, "%ld\r\n", pdf_file->xref_offset); |
eric@59 | 86 | fprintf (pdf_file->f, "%%%%EOF\r\n"); |
eric@59 | 87 | |
eric@59 | 88 | fclose (pdf_file->f); |
eric@59 | 89 | /* should free stuff here */ |
eric@59 | 90 | } |
eric@59 | 91 | |
eric@59 | 92 | |
eric@59 | 93 | void pdf_set_author (pdf_file_handle pdf_file, char *author) |
eric@59 | 94 | { |
eric@59 | 95 | pdf_set_info (pdf_file, "Author", author); |
eric@59 | 96 | } |
eric@59 | 97 | |
eric@59 | 98 | void pdf_set_creator (pdf_file_handle pdf_file, char *creator) |
eric@59 | 99 | { |
eric@59 | 100 | pdf_set_info (pdf_file, "Creator", creator); |
eric@59 | 101 | } |
eric@59 | 102 | |
eric@59 | 103 | void pdf_set_producer (pdf_file_handle pdf_file, char *producer) |
eric@59 | 104 | { |
eric@59 | 105 | pdf_set_info (pdf_file, "Producer", producer); |
eric@59 | 106 | } |
eric@59 | 107 | |
eric@59 | 108 | void pdf_set_title (pdf_file_handle pdf_file, char *title) |
eric@59 | 109 | { |
eric@59 | 110 | pdf_set_info (pdf_file, "Title", title); |
eric@59 | 111 | } |
eric@59 | 112 | |
eric@59 | 113 | void pdf_set_subject (pdf_file_handle pdf_file, char *subject) |
eric@59 | 114 | { |
eric@59 | 115 | pdf_set_info (pdf_file, "Subject", subject); |
eric@59 | 116 | } |
eric@59 | 117 | |
eric@59 | 118 | void pdf_set_keywords (pdf_file_handle pdf_file, char *keywords) |
eric@59 | 119 | { |
eric@59 | 120 | pdf_set_info (pdf_file, "Keywords", keywords); |
eric@59 | 121 | } |
eric@59 | 122 | |
eric@59 | 123 | |
eric@59 | 124 | pdf_page_handle pdf_new_page (pdf_file_handle pdf_file, |
eric@59 | 125 | double width, |
eric@59 | 126 | double height) |
eric@59 | 127 | { |
eric@59 | 128 | pdf_page_handle page = pdf_calloc (sizeof (struct pdf_page)); |
eric@59 | 129 | |
eric@59 | 130 | page->pdf_file = pdf_file; |
eric@59 | 131 | |
eric@59 | 132 | page->media_box = pdf_new_obj (PT_ARRAY); |
eric@59 | 133 | pdf_add_array_elem (page->media_box, pdf_new_real (0)); |
eric@59 | 134 | pdf_add_array_elem (page->media_box, pdf_new_real (0)); |
eric@59 | 135 | pdf_add_array_elem (page->media_box, pdf_new_real (width)); |
eric@59 | 136 | pdf_add_array_elem (page->media_box, pdf_new_real (height)); |
eric@59 | 137 | |
eric@59 | 138 | page->procset = pdf_new_obj (PT_ARRAY); |
eric@59 | 139 | pdf_add_array_elem (page->procset, pdf_new_name ("PDF")); |
eric@59 | 140 | |
eric@59 | 141 | page->resources = pdf_new_obj (PT_DICTIONARY); |
eric@59 | 142 | pdf_set_dict_entry (page->resources, "ProcSet", page->procset); |
eric@59 | 143 | |
eric@59 | 144 | page->page_dict = pdf_new_ind_ref (pdf_file, pdf_new_obj (PT_DICTIONARY)); |
eric@59 | 145 | pdf_set_dict_entry (page->page_dict, "Type", pdf_new_name ("Page")); |
eric@59 | 146 | pdf_set_dict_entry (page->page_dict, "MediaBox", page->media_box); |
eric@59 | 147 | pdf_set_dict_entry (page->page_dict, "Resources", page->resources); |
eric@59 | 148 | |
eric@59 | 149 | /* $$$ currently only support a single-level pages tree */ |
eric@59 | 150 | pdf_set_dict_entry (page->page_dict, "Parent", pdf_file->root->pages_dict); |
eric@59 | 151 | pdf_add_array_elem (pdf_file->root->kids, page->page_dict); |
eric@59 | 152 | pdf_set_integer (pdf_file->root->count, |
eric@59 | 153 | pdf_get_integer (pdf_file->root->count) + 1); |
eric@59 | 154 | |
eric@59 | 155 | page->last_XObject_name = '@'; /* first name will be "ImA" */ |
eric@59 | 156 | |
eric@59 | 157 | return (page); |
eric@59 | 158 | } |
eric@59 | 159 | |
eric@59 | 160 | void pdf_close_page (pdf_page_handle pdf_page) |
eric@59 | 161 | { |
eric@59 | 162 | } |
eric@59 | 163 | |
eric@59 | 164 | |
eric@59 | 165 | void pdf_set_page_number (pdf_page_handle pdf_page, char *page_number) |
eric@59 | 166 | { |
eric@59 | 167 | } |
eric@59 | 168 | |
eric@59 | 169 | void pdf_bookmark (pdf_page_handle pdf_page, int level, char *name) |
eric@59 | 170 | { |
eric@59 | 171 | } |