/* Copyright (C) 1996, 2000, 2001 artofcode LLC. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA, 02111-1307. */ /*$Id: gdevpdfx.h,v 1.34.2.1.2.1 2003/01/17 00:49:01 giles Exp $ */ /* Internal definitions for PDF-writing driver. */ #ifndef gdevpdfx_INCLUDED # define gdevpdfx_INCLUDED #include "gsparam.h" #include "gsuid.h" #include "gxdevice.h" #include "gxfont.h" #include "gxline.h" #include "stream.h" #include "spprint.h" #include "gdevpsdf.h" /* ---------------- Acrobat limitations ---------------- */ /* * The PDF reference manual, 2nd ed., claims that the limit for coordinates * is +/- 32767. However, testing indicates that Acrobat Reader 4 for * Windows and Linux fail with coordinates outside +/- 16383. Hence, we * limit coordinates to 16k, with a little slop. */ #define MAX_USER_COORD 16300 /* ---------------- Statically allocated sizes ---------------- */ /* These should really be dynamic.... */ /* Define the maximum depth of an outline tree. */ /* Note that there is no limit on the breadth of the tree. */ #define MAX_OUTLINE_DEPTH 32 /* Define the maximum size of a destination array string. */ #define MAX_DEST_STRING 80 /* ================ Types and structures ================ */ /* Define the possible contexts for the output stream. */ typedef enum { PDF_IN_NONE, PDF_IN_STREAM, PDF_IN_TEXT, PDF_IN_STRING } pdf_context_t; /* ---------------- Cos objects ---------------- */ /* * These are abstract types for cos objects. The concrete types are in * gdevpdfo.h. */ typedef struct cos_object_s cos_object_t; typedef struct cos_stream_s cos_stream_t; typedef struct cos_dict_s cos_dict_t; typedef struct cos_array_s cos_array_t; typedef struct cos_value_s cos_value_t; typedef struct cos_object_procs_s cos_object_procs_t; typedef const cos_object_procs_t *cos_type_t; #define cos_types_DEFINED /* ---------------- Resources ---------------- */ typedef enum { /* * Standard PDF resources. Font must be last, because resources * up to but not including Font are written page-by-page. */ resourceColorSpace, resourceExtGState, resourcePattern, resourceShading, resourceXObject, resourceFont, /* * Internally used (pseudo-)resources. */ resourceCharProc, resourceCIDFont, resourceCMap, resourceFontDescriptor, resourceFunction, NUM_RESOURCE_TYPES } pdf_resource_type_t; #define PDF_RESOURCE_TYPE_NAMES\ "/ColorSpace", "/ExtGState", "/Pattern", "/Shading", "/XObject", "/Font",\ 0, "/Font", "/CMap", "/FontDescriptor", 0 #define PDF_RESOURCE_TYPE_STRUCTS\ &st_pdf_resource, /* see below */\ &st_pdf_resource,\ &st_pdf_resource,\ &st_pdf_resource,\ &st_pdf_x_object, /* see below */\ &st_pdf_font, /* gdevpdff.h / gdevpdff.c */\ &st_pdf_char_proc, /* gdevpdff.h / gdevpdff.c */\ &st_pdf_font, /* gdevpdff.h / gdevpdff.c */\ &st_pdf_resource,\ &st_pdf_font_descriptor, /* gdevpdff.h / gdevpdff.c */\ &st_pdf_resource /* * rname is currently R for all resources other than synthesized fonts; * for synthesized fonts, rname is A, B, .... The string is null-terminated. */ #define pdf_resource_common(typ)\ typ *next; /* next resource of this type */\ pdf_resource_t *prev; /* previously allocated resource */\ gs_id rid; /* optional ID key */\ bool named;\ char rname[1/*R*/ + (sizeof(long) * 8 / 3 + 1) + 1/*\0*/];\ ulong where_used; /* 1 bit per level of content stream */\ cos_object_t *object typedef struct pdf_resource_s pdf_resource_t; struct pdf_resource_s { pdf_resource_common(pdf_resource_t); }; /* The descriptor is public for subclassing. */ extern_st(st_pdf_resource); #define public_st_pdf_resource() /* in gdevpdfu.c */\ gs_public_st_ptrs3(st_pdf_resource, pdf_resource_t, "pdf_resource_t",\ pdf_resource_enum_ptrs, pdf_resource_reloc_ptrs, next, prev, object) /* * We define XObject resources here because they are used for Image, * Form, and PS XObjects, which are implemented in different files. */ typedef struct pdf_x_object_s pdf_x_object_t; struct pdf_x_object_s { pdf_resource_common(pdf_x_object_t); int width, height; /* specified width and height for images */ int data_height; /* actual data height for images */ }; #define private_st_pdf_x_object() /* in gdevpdfu.c */\ gs_private_st_suffix_add0(st_pdf_x_object, pdf_x_object_t,\ "pdf_x_object_t", pdf_x_object_enum_ptrs, pdf_x_object_reloc_ptrs,\ st_pdf_resource) /* Define the mask for which procsets have been used on a page. */ typedef enum { NoMarks = 0, ImageB = 1, ImageC = 2, ImageI = 4, Text = 8 } pdf_procset_t; /* ------ Fonts ------ */ /* Define the standard fonts. */ #define PDF_NUM_STD_FONTS 14 #define pdf_do_std_fonts(m)\ m("Courier", ENCODING_INDEX_STANDARD)\ m("Courier-Bold", ENCODING_INDEX_STANDARD)\ m("Courier-Oblique", ENCODING_INDEX_STANDARD)\ m("Courier-BoldOblique", ENCODING_INDEX_STANDARD)\ m("Helvetica", ENCODING_INDEX_STANDARD)\ m("Helvetica-Bold", ENCODING_INDEX_STANDARD)\ m("Helvetica-Oblique", ENCODING_INDEX_STANDARD)\ m("Helvetica-BoldOblique", ENCODING_INDEX_STANDARD)\ m("Symbol", ENCODING_INDEX_SYMBOL)\ m("Times-Roman", ENCODING_INDEX_STANDARD)\ m("Times-Bold", ENCODING_INDEX_STANDARD)\ m("Times-Italic", ENCODING_INDEX_STANDARD)\ m("Times-BoldItalic", ENCODING_INDEX_STANDARD)\ m("ZapfDingbats", ENCODING_INDEX_DINGBATS) /* Define the range of synthesized space characters. */ #define X_SPACE_MIN 24 #define X_SPACE_MAX 150 /* Define abstract types. The concrete types are in gdevpdff.h. */ typedef struct pdf_font_s pdf_font_t; /* ------ Named objects ------ */ /* Define an element of the graphics object accumulation (BP/EP) stack. */ typedef struct pdf_graphics_save_s pdf_graphics_save_t; struct pdf_graphics_save_s { pdf_graphics_save_t *prev; cos_stream_t *object; long position; pdf_context_t save_context; pdf_procset_t save_procsets; long save_contents_id; }; #define private_st_pdf_graphics_save() /* in gdevpdfm.c */\ gs_private_st_ptrs2(st_pdf_graphics_save, pdf_graphics_save_t,\ "pdf_graphics_save_t", pdf_graphics_save_enum_ptrs,\ pdf_graphics_save_reloc_ptrs, prev, object) /* ---------------- Other auxiliary structures ---------------- */ /* Outline nodes and levels */ typedef struct pdf_outline_node_s { long id, parent_id, prev_id, first_id, last_id; int count; cos_dict_t *action; } pdf_outline_node_t; typedef struct pdf_outline_level_s { pdf_outline_node_t first; pdf_outline_node_t last; int left; } pdf_outline_level_t; /* * The GC descriptor is implicit, since outline levels occur only in an * embedded array in the gx_device_pdf structure. */ /* Articles */ typedef struct pdf_bead_s { long id, article_id, prev_id, next_id, page_id; gs_rect rect; } pdf_bead_t; typedef struct pdf_article_s pdf_article_t; struct pdf_article_s { pdf_article_t *next; cos_dict_t *contents; pdf_bead_t first; pdf_bead_t last; }; #define private_st_pdf_article()\ gs_private_st_ptrs2(st_pdf_article, pdf_article_t,\ "pdf_article_t", pdf_article_enum_ptrs, pdf_article_reloc_ptrs,\ next, contents) /* ---------------- The device structure ---------------- */ /* Text state */ #ifndef pdf_font_descriptor_DEFINED # define pdf_font_descriptor_DEFINED typedef struct pdf_font_descriptor_s pdf_font_descriptor_t; #endif typedef struct pdf_std_font_s { gs_font *font; /* weak pointer, may be 0 */ pdf_font_descriptor_t *pfd; /* *not* a weak pointer */ gs_matrix orig_matrix; gs_uid uid; /* UniqueID, not XUID */ } pdf_std_font_t; typedef struct pdf_text_state_s { /* State parameters */ float character_spacing; /* Tc */ pdf_font_t *font; /* for Tf */ floatp size; /* for Tf */ float word_spacing; /* Tw */ float leading; /* TL */ bool use_leading; /* true => use ', false => use Tj */ int render_mode; /* Tr */ /* Bookkeeping */ gs_matrix matrix; /* relative to device space, not user space */ gs_point line_start; gs_point current; #define max_text_buffer 200 /* arbitrary, but overflow costs 5 chars */ byte buffer[max_text_buffer]; int buffer_count; } pdf_text_state_t; #define pdf_text_state_default\ 0, NULL, 0, 0, 0, 0 /*false*/, 0,\ { identity_matrix_body }, { 0, 0 }, { 0, 0 }, { 0 }, 0 /* Resource lists */ #define NUM_RESOURCE_CHAINS 16 typedef struct pdf_resource_list_s { pdf_resource_t *chains[NUM_RESOURCE_CHAINS]; } pdf_resource_list_t; /* Define the hash function for gs_ids. */ #define gs_id_hash(rid) ((rid) + ((rid) / NUM_RESOURCE_CHAINS)) /* Define the accessor for the proper hash chain. */ #define PDF_RESOURCE_CHAIN(pdev, type, rid)\ (&(pdev)->resources[type].chains[gs_id_hash(rid) % NUM_RESOURCE_CHAINS]) /* Define the bookkeeping for an open stream. */ typedef struct pdf_stream_position_s { long length_id; long start_pos; } pdf_stream_position_t; /* * Define the structure for keeping track of text rotation. * There is one for the current page (for AutoRotate /PageByPage) * and one for the whole document (for AutoRotate /All). */ typedef struct pdf_text_rotation_s { long counts[5]; /* 0, 90, 180, 270, other */ int Rotate; /* computed rotation, -1 means none */ } pdf_text_rotation_t; #define pdf_text_rotation_angle_values 0, 90, 180, 270, -1 /* * Define document and page information derived from DSC comments. */ typedef struct pdf_page_dsc_info_s { int orientation; /* -1 .. 3 */ int viewing_orientation; /* -1 .. 3 */ gs_rect bounding_box; } pdf_page_dsc_info_t; /* * Define the stored information for a page. Because pdfmarks may add * information to any page anywhere in the document, we have to wait * until the end to write out the page dictionaries. */ typedef struct pdf_page_s { cos_dict_t *Page; gs_point MediaBox; pdf_procset_t procsets; long contents_id; long resource_ids[resourceFont + 1]; /* resources thru Font, see above */ cos_array_t *Annots; pdf_text_rotation_t text_rotation; pdf_page_dsc_info_t dsc_info; } pdf_page_t; #define private_st_pdf_page() /* in gdevpdf.c */\ gs_private_st_ptrs2(st_pdf_page, pdf_page_t, "pdf_page_t",\ pdf_page_enum_ptrs, pdf_page_reloc_ptrs, Page, Annots) /* * Define the structure for the temporary files used while writing. * There are 4 of these, described below. */ typedef struct pdf_temp_file_s { char file_name[gp_file_name_sizeof]; FILE *file; stream *strm; byte *strm_buf; stream *save_strm; /* save pdev->strm while writing here */ } pdf_temp_file_t; /* Define the device structure. */ #ifndef gx_device_pdf_DEFINED # define gx_device_pdf_DEFINED typedef struct gx_device_pdf_s gx_device_pdf; #endif struct gx_device_pdf_s { gx_device_psdf_common; /* PDF-specific distiller parameters */ double CompatibilityLevel; int EndPage; int StartPage; bool Optimize; bool ParseDSCCommentsForDocInfo; bool ParseDSCComments; bool EmitDSCWarnings; bool CreateJobTicket; bool PreserveEPSInfo; bool AutoPositionEPSFiles; bool PreserveCopyPage; bool UsePrologue; /* End of distiller parameters */ /* Other parameters */ bool ReAssignCharacters; bool ReEncodeCharacters; long FirstObjectNumber; /* End of parameters */ /* Values derived from DSC comments */ bool is_EPS; pdf_page_dsc_info_t doc_dsc_info; /* document default */ pdf_page_dsc_info_t page_dsc_info; /* current page */ /* Additional graphics state */ bool fill_overprint, stroke_overprint; int overprint_mode; gs_id halftone_id; gs_id transfer_ids[4]; int transfer_not_identity; /* bitmask */ gs_id black_generation_id, undercolor_removal_id; /* Following are set when device is opened. */ enum { pdf_compress_none, pdf_compress_LZW, /* not currently used, thanks to Unisys */ pdf_compress_Flate } compression; #define pdf_memory v_memory /* * The xref temporary file is logically an array of longs. * xref[id - FirstObjectNumber] is the position in the output file * of the object with the given id. * * Note that xref, unlike the other temporary files, does not have * an associated stream or stream buffer. */ pdf_temp_file_t xref; /* * asides holds resources and other "aside" objects. It is * copied verbatim to the output file at the end of the document. */ pdf_temp_file_t asides; /* * streams holds data for stream-type Cos objects. The data is * copied to the output file at the end of the document. * * Note that streams.save_strm is not used, since we don't interrupt * normal output when saving stream data. */ pdf_temp_file_t streams; /* * pictures holds graphic objects being accumulated between BP and EP. * The object is moved to streams when the EP is reached: since BP and * EP nest, we delete the object from the pictures file at that time. */ pdf_temp_file_t pictures; pdf_font_t *open_font; /* current Type 3 synthesized font */ bool use_open_font; /* if false, start new open_font */ long embedded_encoding_id; int max_embedded_code; /* max Type 3 code used */ long random_offset; /* for generating subset prefixes */ /* ................ */ long next_id; /* The following 3 objects, and only these, are allocated */ /* when the file is opened. */ cos_dict_t *Catalog; cos_dict_t *Info; cos_dict_t *Pages; #define pdf_num_initial_ids 3 long outlines_id; int next_page; long contents_id; pdf_context_t context; long contents_length_id; long contents_pos; pdf_procset_t procsets; /* used on this page */ pdf_text_state_t text; pdf_std_font_t std_fonts[PDF_NUM_STD_FONTS]; long space_char_ids[X_SPACE_MAX - X_SPACE_MIN + 1]; pdf_text_rotation_t text_rotation; #define initial_num_pages 50 pdf_page_t *pages; int num_pages; ulong used_mask; /* for where_used: page level = 1 */ pdf_resource_list_t resources[NUM_RESOURCE_TYPES]; /* cs_Patterns[0] is colored; 1,3,4 are uncolored + Gray,RGB,CMYK */ pdf_resource_t *cs_Patterns[5]; pdf_resource_t *last_resource; pdf_outline_level_t outline_levels[MAX_OUTLINE_DEPTH]; int outline_depth; int closed_outline_depth; int outlines_open; pdf_article_t *articles; cos_dict_t *Dests; cos_dict_t *named_objects; pdf_graphics_save_t *open_graphics; }; #define is_in_page(pdev)\ ((pdev)->contents_id != 0) #define is_in_document(pdev)\ (is_in_page(pdev) || (pdev)->last_resource != 0) /* Enumerate the individual pointers in a gx_device_pdf. */ #define gx_device_pdf_do_ptrs(m)\ m(0,asides.strm) m(1,asides.strm_buf) m(2,asides.save_strm)\ m(3,streams.strm) m(4,streams.strm_buf)\ m(5,pictures.strm) m(6,pictures.strm_buf) m(7,pictures.save_strm)\ m(8,open_font)\ m(9,Catalog) m(10,Info) m(11,Pages)\ m(12,text.font) m(13,pages)\ m(14,cs_Patterns[0])\ m(15,cs_Patterns[1]) m(16,cs_Patterns[3]) m(17,cs_Patterns[4])\ m(18,last_resource)\ m(19,articles) m(20,Dests) m(21,named_objects) m(22,open_graphics) #define gx_device_pdf_num_ptrs 23 #define gx_device_pdf_do_strings(m) /* do nothing */ #define gx_device_pdf_num_strings 0 #define st_device_pdf_max_ptrs\ (st_device_psdf_max_ptrs + gx_device_pdf_num_ptrs +\ gx_device_pdf_num_strings +\ PDF_NUM_STD_FONTS * 2 /* std_fonts[].{font,pfd} */ +\ NUM_RESOURCE_TYPES * NUM_RESOURCE_CHAINS /* resources[].chains[] */ +\ MAX_OUTLINE_DEPTH * 2 /* outline_levels[].{first,last}.action */ #define private_st_device_pdfwrite() /* in gdevpdf.c */\ gs_private_st_composite_final(st_device_pdfwrite, gx_device_pdf,\ "gx_device_pdf", device_pdfwrite_enum_ptrs, device_pdfwrite_reloc_ptrs,\ device_pdfwrite_finalize) /* ================ Driver procedures ================ */ /* In gdevpdfb.c */ dev_proc_copy_mono(gdev_pdf_copy_mono); dev_proc_copy_color(gdev_pdf_copy_color); dev_proc_fill_mask(gdev_pdf_fill_mask); dev_proc_strip_tile_rectangle(gdev_pdf_strip_tile_rectangle); /* In gdevpdfd.c */ extern const gx_device_vector_procs pdf_vector_procs; dev_proc_fill_rectangle(gdev_pdf_fill_rectangle); dev_proc_fill_path(gdev_pdf_fill_path); dev_proc_stroke_path(gdev_pdf_stroke_path); /* In gdevpdfi.c */ dev_proc_begin_typed_image(gdev_pdf_begin_typed_image); /* In gdevpdfp.c */ dev_proc_get_params(gdev_pdf_get_params); dev_proc_put_params(gdev_pdf_put_params); /* In gdevpdft.c */ dev_proc_text_begin(gdev_pdf_text_begin); /* ================ Utility procedures ================ */ /* ---------------- Exported by gdevpdf.c ---------------- */ /* Initialize the IDs allocated at startup. */ void pdf_initialize_ids(P1(gx_device_pdf * pdev)); /* Update the color mapping procedures after setting ProcessColorModel. */ void pdf_set_process_color_model(P1(gx_device_pdf * pdev)); /* Reset the text state parameters to initial values. */ void pdf_reset_text(P1(gx_device_pdf *pdev)); /* ---------------- Exported by gdevpdfu.c ---------------- */ /* ------ Document ------ */ /* Open the document if necessary. */ void pdf_open_document(P1(gx_device_pdf * pdev)); /* ------ Objects ------ */ /* Allocate an ID for a future object. */ long pdf_obj_ref(P1(gx_device_pdf * pdev)); /* Read the current position in the output stream. */ long pdf_stell(P1(gx_device_pdf * pdev)); /* Begin an object, optionally allocating an ID. */ long pdf_open_obj(P2(gx_device_pdf * pdev, long id)); long pdf_begin_obj(P1(gx_device_pdf * pdev)); /* End an object. */ int pdf_end_obj(P1(gx_device_pdf * pdev)); /* ------ Page contents ------ */ /* Open a page contents part. */ /* Return an error if the page has too many contents parts. */ int pdf_open_contents(P2(gx_device_pdf * pdev, pdf_context_t context)); /* Close the current contents part if we are in one. */ int pdf_close_contents(P2(gx_device_pdf * pdev, bool last)); /* ------ Resources et al ------ */ extern const char *const pdf_resource_type_names[]; extern const gs_memory_struct_type_t *const pdf_resource_type_structs[]; /* * Define the offset that indicates that a file position is in the * asides file rather than the main (contents) file. * Must be a power of 2, and larger than the largest possible output file. */ #define ASIDES_BASE_POSITION min_long /* Begin an object logically separate from the contents. */ /* (I.e., an object in the resource file.) */ long pdf_open_separate(P2(gx_device_pdf * pdev, long id)); long pdf_begin_separate(P1(gx_device_pdf * pdev)); /* Begin an aside (resource, annotation, ...). */ int pdf_begin_aside(P4(gx_device_pdf * pdev, pdf_resource_t **plist, const gs_memory_struct_type_t * pst, pdf_resource_t **ppres)); /* Begin a resource of a given type. */ int pdf_begin_resource(P4(gx_device_pdf * pdev, pdf_resource_type_t rtype, gs_id rid, pdf_resource_t **ppres)); /* Begin a resource body of a given type. */ int pdf_begin_resource_body(P4(gx_device_pdf * pdev, pdf_resource_type_t rtype, gs_id rid, pdf_resource_t **ppres)); /* Allocate a resource, but don't open the stream. */ int pdf_alloc_resource(P5(gx_device_pdf * pdev, pdf_resource_type_t rtype, gs_id rid, pdf_resource_t **ppres, long id)); /* Find a resource of a given type by gs_id. */ pdf_resource_t *pdf_find_resource_by_gs_id(P3(gx_device_pdf * pdev, pdf_resource_type_t rtype, gs_id rid)); /* Get the object id of a resource. */ long pdf_resource_id(P1(const pdf_resource_t *pres)); /* End a separate object. */ int pdf_end_separate(P1(gx_device_pdf * pdev)); /* End an aside. */ int pdf_end_aside(P1(gx_device_pdf * pdev)); /* End a resource. */ int pdf_end_resource(P1(gx_device_pdf * pdev)); /* * Write and release the Cos objects for resources local to a content stream. * We must write all the objects before freeing any of them, because * they might refer to each other. */ int pdf_write_resource_objects(P2(gx_device_pdf *pdev, pdf_resource_type_t rtype)); /* * Store the resource sets for a content stream (page or XObject). * Sets page->{procsets, resource_ids[], fonts_id}. */ int pdf_store_page_resources(P2(gx_device_pdf *pdev, pdf_page_t *page)); /* Copy data from a temporary file to a stream. */ void pdf_copy_data(P3(stream *s, FILE *file, long count)); /* ------ Pages ------ */ /* Get or assign the ID for a page. */ /* Returns 0 if the page number is out of range. */ long pdf_page_id(P2(gx_device_pdf * pdev, int page_num)); /* Get the page structure for the current page. */ pdf_page_t *pdf_current_page(P1(gx_device_pdf *pdev)); /* Get the dictionary object for the current page. */ cos_dict_t *pdf_current_page_dict(P1(gx_device_pdf *pdev)); /* Open a page for writing. */ int pdf_open_page(P2(gx_device_pdf * pdev, pdf_context_t context)); /* Write saved page- or document-level information. */ int pdf_write_saved_string(P2(gx_device_pdf * pdev, gs_string * pstr)); /* ------ Path drawing ------ */ /* Test whether the clip path needs updating. */ bool pdf_must_put_clip_path(P2(gx_device_pdf * pdev, const gx_clip_path * pcpath)); /* Write and update the clip path. */ int pdf_put_clip_path(P2(gx_device_pdf * pdev, const gx_clip_path * pcpath)); /* ------ Miscellaneous output ------ */ #define PDF_MAX_PRODUCER 200 /* adhoc */ /* Generate the default Producer string. */ void pdf_store_default_Producer(P1(char buf[PDF_MAX_PRODUCER])); /* Define the strings for filter names and parameters. */ typedef struct pdf_filter_names_s { const char *ASCII85Decode; const char *ASCIIHexDecode; const char *CCITTFaxDecode; const char *DCTDecode; const char *DecodeParms; const char *Filter; const char *FlateDecode; const char *LZWDecode; const char *RunLengthDecode; } pdf_filter_names_t; #define PDF_FILTER_NAMES\ "/ASCII85Decode", "/ASCIIHexDecode", "/CCITTFaxDecode",\ "/DCTDecode", "/DecodeParms", "/Filter", "/FlateDecode",\ "/LZWDecode", "/RunLengthDecode" #define PDF_FILTER_NAMES_SHORT\ "/A85", "/AHx", "/CCF", "/DCT", "/DP", "/F", "/Fl", "/LZW", "/RL" /* Write matrix values. */ void pdf_put_matrix(P4(gx_device_pdf *pdev, const char *before, const gs_matrix *pmat, const char *after)); /* Write a name, with escapes for unusual characters. */ typedef int (*pdf_put_name_chars_proc_t)(P3(stream *, const byte *, uint)); pdf_put_name_chars_proc_t pdf_put_name_chars_proc(P1(const gx_device_pdf *pdev)); void pdf_put_name_chars(P3(const gx_device_pdf *pdev, const byte *nstr, uint size)); void pdf_put_name(P3(const gx_device_pdf *pdev, const byte *nstr, uint size)); /* Write a string in its shortest form ( () or <> ). */ void pdf_put_string(P3(const gx_device_pdf *pdev, const byte *str, uint size)); /* Write a value, treating names specially. */ void pdf_write_value(P3(const gx_device_pdf *pdev, const byte *vstr, uint size)); /* Store filters for a stream. */ int pdf_put_filters(P4(cos_dict_t *pcd, gx_device_pdf *pdev, stream *s, const pdf_filter_names_t *pfn)); /* Define a possibly encoded and compressed data stream. */ typedef struct pdf_data_writer_s { psdf_binary_writer binary; long start; long length_id; } pdf_data_writer_t; /* * Begin a data stream. The client has opened the object and written * the << and any desired dictionary keys. */ int pdf_begin_data_binary(P3(gx_device_pdf *pdev, pdf_data_writer_t *pdw, bool data_is_binary)); #define pdf_begin_data(pdev, pdw) pdf_begin_data_binary(pdev, pdw, true) /* End a data stream. */ int pdf_end_data(P1(pdf_data_writer_t *pdw)); /* Define the maximum size of a Function reference. */ #define MAX_REF_CHARS ((sizeof(long) * 8 + 2) / 3) /* Create a Function object. */ #ifndef gs_function_DEFINED typedef struct gs_function_s gs_function_t; # define gs_function_DEFINED #endif int pdf_function(P3(gx_device_pdf *pdev, const gs_function_t *pfn, cos_value_t *pvalue)); /* Write a Function object, returning its object ID. */ int pdf_write_function(P3(gx_device_pdf *pdev, const gs_function_t *pfn, long *pid)); /* ---------------- Exported by gdevpdfm.c ---------------- */ /* * Define the type for a pdfmark-processing procedure. * If nameable is false, the objname argument is always NULL. */ #define pdfmark_proc(proc)\ int proc(P5(gx_device_pdf *pdev, gs_param_string *pairs, uint count,\ const gs_matrix *pctm, const gs_param_string *objname)) /* Compare a C string and a gs_param_string. */ bool pdf_key_eq(P2(const gs_param_string * pcs, const char *str)); /* Scan an integer out of a parameter string. */ int pdfmark_scan_int(P2(const gs_param_string * pstr, int *pvalue)); /* Process a pdfmark (called from pdf_put_params). */ int pdfmark_process(P2(gx_device_pdf * pdev, const gs_param_string_array * pma)); /* Close the current level of the outline tree. */ int pdfmark_close_outline(P1(gx_device_pdf * pdev)); /* Finish writing an article. */ int pdfmark_write_article(P2(gx_device_pdf * pdev, const pdf_article_t * part)); /* ---------------- Exported by gdevpdfr.c ---------------- */ /* Test whether an object name has valid syntax, {name}. */ bool pdf_objname_is_valid(P2(const byte *data, uint size)); /* * Look up a named object. Return e_rangecheck if the syntax is invalid, * e_undefined if no object by that name exists. */ int pdf_find_named(P3(gx_device_pdf * pdev, const gs_param_string * pname, cos_object_t **ppco)); /* * Create a named object. id = -1L means do not assign an id. pname = 0 * means just create the object, do not name it. */ int pdf_create_named(P5(gx_device_pdf *pdev, const gs_param_string *pname, cos_type_t cotype, cos_object_t **ppco, long id)); int pdf_create_named_dict(P4(gx_device_pdf *pdev, const gs_param_string *pname, cos_dict_t **ppcd, long id)); /* * Look up a named object as for pdf_find_named. If the object does not * exist, create it (as a dictionary if it is one of the predefined names * {ThisPage}, {NextPage}, {PrevPage}, or {Page<#>}, otherwise as a * generic object) and return 1. */ int pdf_refer_named(P3(gx_device_pdf *pdev, const gs_param_string *pname, cos_object_t **ppco)); /* * Look up a named object as for pdf_refer_named. If the object already * exists and is not simply a forward reference, return e_rangecheck; * if it exists as a forward reference, set its type and return 0; * otherwise, create the object with the given type and return 1. * pname = 0 is allowed: in this case, simply create the object. */ int pdf_make_named(P5(gx_device_pdf * pdev, const gs_param_string * pname, cos_type_t cotype, cos_object_t **ppco, bool assign_id)); int pdf_make_named_dict(P4(gx_device_pdf * pdev, const gs_param_string * pname, cos_dict_t **ppcd, bool assign_id)); /* * Look up a named object as for pdf_refer_named. If the object does not * exist, or is a forward reference, return e_undefined; if the object * exists has the wrong type, return e_typecheck. */ int pdf_get_named(P4(gx_device_pdf * pdev, const gs_param_string * pname, cos_type_t cotype, cos_object_t **ppco)); /* * Scan a string for a token. <<, >>, [, and ] are treated as tokens. * Return 1 if a token was scanned, 0 if we reached the end of the string, * or an error. On a successful return, the token extends from *ptoken up * to but not including *pscan. */ int pdf_scan_token(P3(const byte **pscan, const byte * end, const byte **ptoken)); /* * Scan a possibly composite token: arrays and dictionaries are treated as * single tokens. */ int pdf_scan_token_composite(P3(const byte **pscan, const byte * end, const byte **ptoken)); /* Replace object names with object references in a (parameter) string. */ int pdf_replace_names(P3(gx_device_pdf *pdev, const gs_param_string *from, gs_param_string *to)); #endif /* gdevpdfx_INCLUDED */