1 /* Copyright (C) 1999, 2000 Aladdin Enterprises. All rights reserved. 2 3 This software is provided AS-IS with no warranty, either express or 4 implied. 5 6 This software is distributed under license and may not be copied, 7 modified or distributed except as expressly authorized under the terms 8 of the license contained in the file LICENSE in this distribution. 9 10 For more information about licensing, please refer to 11 http://www.ghostscript.com/licensing/. For information on 12 commercial licensing, go to http://www.artifex.com/licensing/ or 13 contact Artifex Software, Inc., 101 Lucas Valley Road #110, 14 San Rafael, CA 94903, U.S.A., +1(415)492-9861. 15 */ 16 17 /* $Id: gdevpdfo.h,v 1.19 2004/06/08 11:43:04 igor Exp $ */ 18 /* Internal definitions for "objects" for pdfwrite driver. */ 19 20 #ifndef gdevpdfo_INCLUDED 21 # define gdevpdfo_INCLUDED 22 23 /* 24 * This file defines the structures and support procedures for what Adobe 25 * calls "Cos objects". (We don't know what "Cos" stands for, but in our 26 * case, it's a good acronym for "Collection and stream".) We only 27 * support arrays, dictionaries, and streams: we merge all other types into a 28 * single string type, which holds the printed representation that will be 29 * written on the output file, and we only support that type as an element 30 * of the collection types. 31 * 32 * Note that Cos objects are *not* reference-counted. Objects without 33 * an ID are assumed to be referenced from only one place; objects with 34 * IDs are managed manually. We also assume that strings (the keys of 35 * dictionaries, and non-object values in arrays and dictionaries) are 36 * "owned" by their referencing object. 37 */ 38 39 #include "gsparam.h" 40 41 /* Define some needed abstract types. */ 42 #ifndef gx_device_pdf_DEFINED 43 # define gx_device_pdf_DEFINED 44 typedef struct gx_device_pdf_s gx_device_pdf; 45 #endif 46 47 /* ---------------- Structures ---------------- */ 48 49 /* Define the abstract types if they aren't defined already (in gdevpdfx.h). */ 50 #ifndef cos_types_DEFINED 51 # define cos_types_DEFINED 52 typedef struct cos_object_s cos_object_t; 53 typedef struct cos_stream_s cos_stream_t; 54 typedef struct cos_dict_s cos_dict_t; 55 typedef struct cos_array_s cos_array_t; 56 typedef struct cos_value_s cos_value_t; 57 typedef struct cos_object_procs_s cos_object_procs_t; 58 typedef const cos_object_procs_t *cos_type_t; 59 #endif 60 61 /* Abstract types (defined concretely in gdevpdfo.c) */ 62 typedef struct cos_element_s cos_element_t; 63 typedef struct cos_stream_piece_s cos_stream_piece_t; 64 65 /* 66 * Define the object procedures for Cos objects. 67 */ 68 /*typedef struct cos_object_s cos_object_t;*/ 69 /*typedef*/ struct cos_object_procs_s { 70 71 #define cos_proc_release(proc)\ 72 void proc(cos_object_t *pco, client_name_t cname) 73 cos_proc_release((*release)); 74 75 #define cos_proc_write(proc)\ 76 int proc(const cos_object_t *pco, gx_device_pdf *pdev, gs_id object_id) 77 cos_proc_write((*write)); 78 79 #define cos_proc_equal(proc)\ 80 int proc(const cos_object_t *pco0, const cos_object_t *pco1, gx_device_pdf *pdev) 81 cos_proc_equal((*equal)); 82 83 } /*cos_object_procs_t*/; 84 /*typedef const cos_object_procs_t *cos_type_t;*/ 85 #define cos_type(pco) ((pco)->cos_procs) 86 87 /* 88 * Define the generic structure for Cos objects. Note that all Cos 89 * objects have the same structure and type, aside from their elements. 90 * This allows us to "mutate" a forward-referenced object into its 91 * proper type in place. 92 * 93 * Note that we distinguish elements from contents. Arrays and 94 * dictionaries have only elements; streams have both elements 95 * (additional elements of the stream dictionary) and contents pieces. 96 * 97 * The is_open member currently has no function other than error checking. 98 * It is set to true when the object is created, to false by the CLOSE 99 * and EP pdfmarks, and is checked by CLOSE, PUT, and SP. 100 * 101 * The is_graphics member exists only to ensure that the stream argument 102 * of SP was created by BP/EP. 103 * 104 * The written member records whether the object has been written (copied) 105 * into the contents or resource file. 106 */ 107 #define cos_object_struct(otype_s, etype)\ 108 struct otype_s {\ 109 const cos_object_procs_t *cos_procs; /* must be first */\ 110 long id;\ 111 etype *elements;\ 112 cos_stream_piece_t *pieces;\ 113 gx_device_pdf *pdev;\ 114 pdf_resource_t *pres; /* only for BP/EP XObjects */\ 115 byte is_open; /* see above */\ 116 byte is_graphics; /* see above */\ 117 byte written; /* see above */\ 118 long length; /* only for stream objects */\ 119 stream *input_strm; /* only for stream objects */\ 120 /* input_strm is introduced recently for pdfmark. */\ 121 /* Using this field, psdf_binary_writer_s may be simplified. */\ 122 } 123 cos_object_struct(cos_object_s, cos_element_t); 124 #define private_st_cos_object() /* in gdevpdfo.c */\ 125 gs_private_st_ptrs5(st_cos_object, cos_object_t, "cos_object_t",\ 126 cos_object_enum_ptrs, cos_object_reloc_ptrs, elements, pieces,\ 127 pdev, pres, input_strm) 128 extern const cos_object_procs_t cos_generic_procs; 129 #define cos_type_generic (&cos_generic_procs) 130 131 /* 132 * Define the macro for casting any cos object to type cos_object_t. 133 * Using cos_procs ensures that the argument is, in fact, a cos object. 134 */ 135 #define COS_OBJECT(pc) ((cos_object_t *)&((pc)->cos_procs)) 136 #define CONST_COS_OBJECT(pc) ((const cos_object_t *)&((pc)->cos_procs)) 137 138 /* 139 * Define the structure for the value of an array or dictionary element. 140 * This is where we create the union of composite and scalar types. 141 */ 142 /*typedef struct cos_value_s cos_value_t;*/ 143 typedef enum { 144 COS_VALUE_SCALAR = 0, /* heap-allocated string */ 145 COS_VALUE_CONST, /* shared (constant) string */ 146 COS_VALUE_OBJECT, /* object referenced by # # R */ 147 COS_VALUE_RESOURCE /* object referenced by /R# */ 148 } cos_value_type_t; 149 struct cos_value_s { 150 cos_value_type_t value_type; 151 union vc_ { 152 gs_string chars; /* SCALAR, CONST */ 153 cos_object_t *object; /* OBJECT, RESOURCE */ 154 } contents; 155 }; 156 #define private_st_cos_value() /* in gdevpdfo.c */\ 157 gs_private_st_composite(st_cos_value, cos_value_t,\ 158 "cos_value_t", cos_value_enum_ptrs, cos_value_reloc_ptrs) 159 160 /* 161 * Define Cos arrays, dictionaries, and streams. 162 * 163 * The elements of arrays are stored sorted in decreasing index order. 164 * The elements of dictionaries/streams are not sorted. 165 * The contents pieces of streams are stored in reverse order. 166 */ 167 /* array */ 168 typedef struct cos_array_element_s cos_array_element_t; 169 cos_object_struct(cos_array_s, cos_array_element_t); 170 extern const cos_object_procs_t cos_array_procs; 171 #define cos_type_array (&cos_array_procs) 172 /* dict */ 173 typedef struct cos_dict_element_s cos_dict_element_t; 174 cos_object_struct(cos_dict_s, cos_dict_element_t); 175 extern const cos_object_procs_t cos_dict_procs; 176 #define cos_type_dict (&cos_dict_procs) 177 /* stream */ 178 cos_object_struct(cos_stream_s, cos_dict_element_t); 179 extern const cos_object_procs_t cos_stream_procs; 180 #define cos_type_stream (&cos_stream_procs) 181 182 /* ---------------- Procedures ---------------- */ 183 184 /* 185 * NOTE: Procedures that include "_c_" in their name do not copy their C 186 * string argument(s). To copy the argument, use the procedure that takes 187 * a byte pointer and a length. 188 */ 189 190 /* Create a Cos object. */ 191 cos_object_t *cos_object_alloc(gx_device_pdf *, client_name_t); 192 cos_array_t *cos_array_alloc(gx_device_pdf *, client_name_t); 193 cos_array_t *cos_array_from_floats(gx_device_pdf *, const float *, uint, 194 client_name_t); 195 cos_dict_t *cos_dict_alloc(gx_device_pdf *, client_name_t); 196 cos_stream_t *cos_stream_alloc(gx_device_pdf *, client_name_t); 197 198 /* Get the allocator for a Cos object. */ 199 gs_memory_t *cos_object_memory(const cos_object_t *); 200 #define COS_OBJECT_MEMORY(pc) cos_object_memory(CONST_COS_OBJECT(pc)) 201 202 /* Set the type of a generic Cos object. */ 203 int cos_become(cos_object_t *, cos_type_t); 204 205 /* Define wrappers for calling the object procedures. */ 206 cos_proc_release(cos_release); 207 #define COS_RELEASE(pc, cname) cos_release(COS_OBJECT(pc), cname) 208 cos_proc_write(cos_write); 209 #define COS_WRITE(pc, pdev) cos_write(CONST_COS_OBJECT(pc), pdev, (pc)->id) 210 211 /* Make a value to store into a composite object. */ 212 const cos_value_t *cos_string_value(cos_value_t *, const byte *, uint); 213 const cos_value_t *cos_c_string_value(cos_value_t *, const char *); 214 const cos_value_t *cos_object_value(cos_value_t *, cos_object_t *); 215 #define COS_OBJECT_VALUE(pcv, pc) cos_object_value(pcv, COS_OBJECT(pc)) 216 /* A resource value is an object value referenced as /R#, not # # R. */ 217 const cos_value_t *cos_resource_value(cos_value_t *, cos_object_t *); 218 #define COS_RESOURCE_VALUE(pcv, pc) cos_resource_value(pcv, COS_OBJECT(pc)) 219 220 /* Test whether a value is an object */ 221 #define COS_VALUE_IS_OBJECT(pv) ((pv)->value_type >= COS_VALUE_OBJECT) 222 223 /* 224 * Put an element in / add an element to a Cos object. The _no_copy 225 * procedures assume that the value, if not an object, is a newly allocated, 226 * unshared string, allocated by the same allocator as the collection 227 * itself, that should not be copied. 228 */ 229 /* array */ 230 int cos_array_put(cos_array_t *, long, const cos_value_t *); 231 int cos_array_put_no_copy(cos_array_t *, long, const cos_value_t *); 232 int cos_array_add(cos_array_t *, const cos_value_t *); 233 int cos_array_add_no_copy(cos_array_t *, const cos_value_t *); 234 int cos_array_add_c_string(cos_array_t *, const char *); 235 int cos_array_add_int(cos_array_t *, int); 236 int cos_array_add_real(cos_array_t *, floatp); 237 int cos_array_add_object(cos_array_t *, cos_object_t *); 238 /* add adds at the end, unadd removes the last element */ 239 int cos_array_unadd(cos_array_t *, cos_value_t *); 240 /* dict */ 241 int cos_dict_put(cos_dict_t *, const byte *, uint, const cos_value_t *); 242 int cos_dict_put_no_copy(cos_dict_t *, const byte *, uint, 243 const cos_value_t *); 244 int cos_dict_put_c_key(cos_dict_t *, const char *, const cos_value_t *); 245 int cos_dict_put_c_key_string(cos_dict_t *, const char *, const byte *, uint); 246 int cos_dict_put_c_key_int(cos_dict_t *, const char *, int); 247 int cos_dict_put_c_key_bool(cos_dict_t *pcd, const char *key, bool value); 248 int cos_dict_put_c_key_real(cos_dict_t *, const char *, floatp); 249 int cos_dict_put_c_key_floats(cos_dict_t *, const char *, const float *, uint); 250 int cos_dict_put_c_key_object(cos_dict_t *, const char *, cos_object_t *); 251 int cos_dict_put_string(cos_dict_t *, const byte *, uint, const byte *, uint); 252 int cos_dict_put_string_copy(cos_dict_t *pcd, const char *key, const char *value); 253 int cos_dict_put_c_strings(cos_dict_t *, const char *, const char *); 254 /* move all the elements from one dict to another */ 255 int cos_dict_move_all(cos_dict_t *, cos_dict_t *); 256 /* stream */ 257 int cos_stream_add(cos_stream_t *, uint); 258 int cos_stream_add_bytes(cos_stream_t *, const byte *, uint); 259 int cos_stream_add_stream_contents(cos_stream_t *, stream *); 260 int cos_stream_release_pieces(cos_stream_t *pcs); 261 cos_dict_t *cos_stream_dict(cos_stream_t *); 262 263 /* 264 * Get the first / next element for enumerating an array. Usage: 265 * const cos_array_element_t *elt = cos_array_element_first(pca); 266 * while (elt) { 267 * long idx; 268 * const cos_value_t *pvalue; 269 * elt = cos_array_element_next(elt, &idx, &pvalue); 270 * ... 271 * } 272 * The order in which the elements are returned is not defined. 273 * If the client adds elements to the array during the enumeration, 274 * they may or may not be included in the enumeration. 275 */ 276 const cos_array_element_t * 277 cos_array_element_first(const cos_array_t *); 278 const cos_array_element_t * 279 cos_array_element_next(const cos_array_element_t *, long *, 280 const cos_value_t **); 281 282 /* Look up a key in a dictionary. */ 283 const cos_value_t *cos_dict_find(const cos_dict_t *, const byte *, uint); 284 const cos_value_t *cos_dict_find_c_key(const cos_dict_t *, const char *); 285 286 /* Set up a parameter list that writes into a Cos dictionary. */ 287 typedef struct cos_param_list_writer_s { 288 gs_param_list_common; 289 cos_dict_t *pcd; 290 int print_ok; 291 } cos_param_list_writer_t; 292 int cos_param_list_writer_init(cos_param_list_writer_t *, cos_dict_t *, 293 int print_ok); 294 295 /* Create a stream that writes into a Cos stream. */ 296 /* Closing the stream will free it. */ 297 stream *cos_write_stream_alloc(cos_stream_t *pcs, gx_device_pdf *pdev, 298 client_name_t cname); 299 300 /* Get cos stream from pipeline. */ 301 cos_stream_t * cos_stream_from_pipeline(stream *s); 302 /* Get cos write stream from pipeline. */ 303 stream * cos_write_stream_from_pipeline(stream *s); 304 305 /* Write a Cos value on the output. */ 306 int cos_value_write(const cos_value_t *, gx_device_pdf *); 307 308 /* Write the elements of a dictionary/stream on the output. */ 309 int cos_dict_elements_write(const cos_dict_t *, gx_device_pdf *); 310 int cos_stream_elements_write(const cos_stream_t *, gx_device_pdf *); /* = dict_elements_write */ 311 int cos_stream_contents_write(const cos_stream_t *, gx_device_pdf *); 312 313 /* Find the total length of a stream. */ 314 long cos_stream_length(const cos_stream_t *pcs); 315 316 /* Write/delete definitions of named objects. */ 317 /* This is a special-purpose facility for pdf_close. */ 318 int cos_dict_objects_write(const cos_dict_t *, gx_device_pdf *); 319 int cos_dict_objects_delete(cos_dict_t *); 320 321 /* Write a cos object as a PDF object. */ 322 int cos_write_object(cos_object_t *pco, gx_device_pdf *pdev); 323 #define COS_WRITE_OBJECT(pc, pdev) cos_write_object(COS_OBJECT(pc), pdev) 324 325 /* Free a Cos value owned by a Cos object. */ 326 void cos_value_free(const cos_value_t *, const cos_object_t *, client_name_t); 327 328 /* Free a cos object. */ 329 void cos_free(cos_object_t *pco, client_name_t cname); 330 #define COS_FREE(pc, cname) cos_free(COS_OBJECT(pc), cname) 331 332 #endif /* gdevpdfo_INCLUDED */ 333