/* Copyright (C) 1999, 2000 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: gdevpdff.h,v 1.11.2.1.2.1 2003/01/17 00:49:01 giles Exp $ */ /* Font-related definitions for PDF-writing driver. */ #ifndef gdevpdff_INCLUDED # define gdevpdff_INCLUDED /* ================ Types and structures ================ */ /* * The PDF writer creates several different kinds of font resources. * The key differences between them are the values of num_chars, index, * and descriptor. * * - Synthesized Type 3 bitmap fonts are identified by num_chars != 0 (or * equivalently PDF_FONT_IS_SYNTHESIZED = true). They have index < 0, * FontDescriptor == 0. All other fonts have num_chars == 0. * * - Type 0 fonts have num_chars == 0, index < 0, FontDescriptor == 0. * All other non-synthesized fonts have FontDescriptor != 0. * * - The base 14 fonts (when not embedded) have num_chars == 0, index * >= 0, FontDescriptor != 0, FontDescriptor->base_font == 0. All * other fonts have index < 0. * * - All other fonts, embedded or not, have num_chars == 0, index < 0, * FontDescriptor != 0, FontDescriptor->base_font != 0. A font is * embedded iff FontDescriptor->FontFile_id != 0. * * For non-synthesized fonts, the structure representation is designed to * represent directly the information that will be written in the font * resource, Encoding, and FontDescriptor dictionaries. See the comments * on the pdf_font_t structure below for more detail. */ /* * PDF font names must be large enough for the 14 built-in fonts, * and also large enough for any reasonable font name + 7 characters * for the subsetting prefix + a suffix derived from the PDF object number. */ #define SUBSET_PREFIX_SIZE 7 #define MAX_PDF_FONT_NAME\ (SUBSET_PREFIX_SIZE + gs_font_name_max + 1 + 1 + sizeof(long) * 2) typedef struct pdf_font_name_s { byte chars[MAX_PDF_FONT_NAME]; uint size; } pdf_font_name_t; /* ---------------- Font descriptor (pseudo-resource) ---------------- */ /* * A FontDescriptor refers to an unscaled, possibly built-in base_font. * Multiple pdf_fonts with the same outlines (but possibly different * encodings, metrics, and scaling) may share a single FontDescriptor. * Each such pdf_font refers to a corresponding gs_font object, and * the gs_fonts of all such pdf_fonts will have the base_font of the * FontDescriptor as their eventual base font (through a chain of 0 or * more base pointers). * * Since gs_font objects may be freed at any time, we register a procedure * to be called when that happens. The (gs_)font of a pdf_font may be freed * either before or after the base_font in the FontDescriptor. Therefore, a * pdf_font copies enough information from its gs_font that when the gs_font * is freed, the pdf_font still has enough information to write the Font * resource dictionary at a later time. When freeing a gs_font referenced * from a pdf_font, we only clear the pointer to it from its referencing * pdf_font. However, when the base_font of a FontDescriptor is about to be * freed, we must write the FontDescriptor, and, if the font is embedded, * the FontFile data. */ /* * Font descriptors are handled as pseudo-resources. Multiple pdf_fonts * may share a descriptor. We don't need to use reference counting to * keep track of this, since all descriptors persist until the device * is closed, even though the base_font they reference may have been * freed. */ typedef struct pdf_font_descriptor_values_s { font_type FontType; /* copied from font */ /* Required elements */ int Ascent, CapHeight, Descent, ItalicAngle, StemV; gs_int_rect FontBBox; uint Flags; /* Optional elements (default to 0) */ int AvgWidth, Leading, MaxWidth, MissingWidth, StemH, XHeight; } pdf_font_descriptor_values_t; #ifndef pdf_font_descriptor_DEFINED # define pdf_font_descriptor_DEFINED typedef struct pdf_font_descriptor_s pdf_font_descriptor_t; #endif /* * Define whether an embedded font must, may, or must not be subsetted. */ typedef enum { FONT_SUBSET_OK, FONT_SUBSET_YES, FONT_SUBSET_NO } pdf_font_do_subset_t; typedef enum { FONT_EMBED_STANDARD, /* 14 standard fonts */ FONT_EMBED_NO, FONT_EMBED_YES } pdf_font_embed_t; struct pdf_font_descriptor_s { pdf_resource_common(pdf_font_descriptor_t); pdf_font_name_t FontName; pdf_font_descriptor_values_t values; gs_matrix orig_matrix; /* unscaled font matrix */ uint chars_count; /* size of chars_used in bits */ gs_string chars_used; /* 1 bit per character code or CID */ uint glyphs_count; /* size of glyphs_used in bits */ gs_string glyphs_used; /* 1 bit per glyph, for TrueType fonts */ pdf_font_do_subset_t do_subset; long FontFile_id; /* non-0 iff the font is embedded */ gs_font *base_font; /* unscaled font defining the base encoding, */ /* matrix, and character set, 0 iff */ /* non-embedded standard font */ bool notified; /* if true, base_font will notify on freeing */ bool written; /* if true, descriptor has been written out */ }; /* Flag bits */ /*#define FONT_IS_FIXED_WIDTH (1<<0)*/ /* defined in gxfont.h */ #define FONT_IS_SERIF (1<<1) #define FONT_IS_SYMBOLIC (1<<2) #define FONT_IS_SCRIPT (1<<3) /* * There is confusion over the meaning of the 1<<5 bit. According to the * published PDF documentation, in PDF 1.1, it meant "font uses * StandardEncoding", and as of PDF 1.2, it means "font uses (a subset of) * the Adobe standard Latin character set"; however, Acrobat Reader 3 and 4 * seem to use the former interpretation, even if the font is embedded and * the file is identified as a PDF 1.2 file. We have to use the former * interpretation in order to produce output that Acrobat will handle * correctly. */ #define FONT_USES_STANDARD_ENCODING (1<<5) /* always used */ #define FONT_IS_ADOBE_ROMAN (1<<5) /* never used */ #define FONT_IS_ITALIC (1<<6) #define FONT_IS_ALL_CAPS (1<<16) #define FONT_IS_SMALL_CAPS (1<<17) #define FONT_IS_FORCE_BOLD (1<<18) /* * Font descriptors are pseudo-resources, so their GC descriptors * must be public. */ #define public_st_pdf_font_descriptor() /* in gdevpdff.c */\ BASIC_PTRS(pdf_font_descriptor_ptrs) {\ GC_STRING_ELT(pdf_font_descriptor_t, chars_used),\ GC_STRING_ELT(pdf_font_descriptor_t, glyphs_used),\ GC_OBJ_ELT(pdf_font_descriptor_t, base_font)\ };\ gs_public_st_basic_super(st_pdf_font_descriptor, pdf_font_descriptor_t,\ "pdf_font_descriptor_t", pdf_font_descriptor_ptrs,\ pdf_font_descriptor_data, &st_pdf_resource, 0) /* ---------------- Font (resource) ---------------- */ typedef struct pdf_char_proc_s pdf_char_proc_t; /* forward reference */ /*typedef struct pdf_font_s pdf_font_t;*/ typedef struct pdf_encoding_element_s { gs_glyph glyph; gs_const_string str; } pdf_encoding_element_t; #define private_st_pdf_encoding_element()\ gs_private_st_composite(st_pdf_encoding_element, pdf_encoding_element_t,\ "pdf_encoding_element_t[]", pdf_encoding_elt_enum_ptrs,\ pdf_encoding_elt_reloc_ptrs) /* * Structure elements beginning with a capital letter correspond directly * to keys in the font or Encoding dictionary. Currently these are: * (font) FontType, FirstChar, LastChar, Widths, FontDescriptor, * DescendantFont[s] * (Encoding) BaseEncoding, Differences * This structure is untidy: it is really a union of 4 different variants * (plain font, composite font, CIDFont, synthesized font). It's simpler * to "flatten" the union. */ struct pdf_font_s { pdf_resource_common(pdf_font_t); pdf_font_name_t fname; font_type FontType; gs_font *font; /* non-0 iff font will notify us; */ /* should be a weak pointer */ int index; /* in pdf_standard_fonts, -1 if not base 14 */ pdf_font_embed_t embed; /* status of pdf_font_embed_status() */ gs_matrix orig_matrix; /* FontMatrix of unscaled font for embedding */ bool is_MM_instance; /* for Type 1/2 fonts, true iff the font */ /* is a Multiple Master instance */ /* Members for all non-synthesized fonts. */ pdf_font_descriptor_t *FontDescriptor; /* 0 for composite */ bool write_Widths; int *Widths; /* [256] for non-composite, non-CID */ byte *widths_known; /* 1 bit per Widths element */ /* Members for non-synthesized fonts other than composite or CID. */ int FirstChar, LastChar; /* Encoding for base fonts. */ gs_encoding_index_t BaseEncoding; pdf_encoding_element_t *Differences; /* [256] */ /* Members for composite fonts (with FMapType = fmap_CMap). */ pdf_font_t *DescendantFont; /* CIDFont */ char cmapname[max( /* standard name or 0 R */ 16, /* UniJIS-UCS2-HW-H */ sizeof(long) * 8 / 3 + 1 + 4 /* 0 R */ ) + 1]; font_type sub_font_type; /* FontType of DescendantFont */ /* Members for CIDFonts. */ long CIDSystemInfo_id; pdf_font_t *glyphshow_font; /* type 0 font created for glyphshow */ ushort *CIDToGIDMap; /* CIDFontType 2 only */ /* Members for synthesized fonts. */ int num_chars; #define PDF_FONT_IS_SYNTHESIZED(pdfont) ((pdfont)->num_chars != 0) pdf_char_proc_t *char_procs; int max_y_offset; /* Pseudo-characters for spacing. */ /* The range should be determined by the device resolution.... */ /*#define X_SPACE_MIN xxx*/ /* in gdevpdfx.h */ /*#define X_SPACE_MAX nnn*/ /* in gdevpdfx.h */ byte spaces[X_SPACE_MAX - X_SPACE_MIN + 1]; }; /* The descriptor is public for pdf_resource_type_structs. */ #define public_st_pdf_font()\ gs_public_st_suffix_add9(st_pdf_font, pdf_font_t, "pdf_font_t",\ pdf_font_enum_ptrs, pdf_font_reloc_ptrs, st_pdf_resource,\ font, FontDescriptor, Widths, widths_known, Differences, DescendantFont,\ glyphshow_font, CIDToGIDMap, char_procs) /* CharProc pseudo-resources for synthesized fonts */ struct pdf_char_proc_s { pdf_resource_common(pdf_char_proc_t); pdf_font_t *font; pdf_char_proc_t *char_next; /* next char_proc for same font */ int width, height; int x_width; /* X escapement */ int y_offset; /* of character (0,0) */ byte char_code; }; /* The descriptor is public for pdf_resource_type_structs. */ #define public_st_pdf_char_proc()\ gs_public_st_suffix_add2(st_pdf_char_proc, pdf_char_proc_t,\ "pdf_char_proc_t", pdf_char_proc_enum_ptrs,\ pdf_char_proc_reloc_ptrs, st_pdf_resource, font, char_next) /* ================ Procedures ================ */ /* ---------------- Exported by gdevpdft.c ---------------- */ /* For gdevpdfs.c */ /* Define the text enumerator. */ typedef struct pdf_text_enum_s { gs_text_enum_common; gs_text_enum_t *pte_default; gs_fixed_point origin; } pdf_text_enum_t; #define private_st_pdf_text_enum() /* in gdevpdft.c */\ extern_st(st_gs_text_enum);\ gs_private_st_suffix_add1(st_pdf_text_enum, pdf_text_enum_t,\ "pdf_text_enum_t", pdf_text_enum_enum_ptrs, pdf_text_enum_reloc_ptrs,\ st_gs_text_enum, pte_default) /* * Set the current font and size, writing a Tf command if needed. */ int pdf_set_font_and_size(P3(gx_device_pdf * pdev, pdf_font_t * font, floatp size)); /* * Set the text matrix for writing text, writing a Tm, TL, or Tj command * if needed. */ int pdf_set_text_matrix(P2(gx_device_pdf * pdev, const gs_matrix * pmat)); /* * Append characters to a string being accumulated. */ int pdf_append_chars(P3(gx_device_pdf * pdev, const byte * str, uint size)); /* For gdevpdfb.c */ /* Begin a CharProc for an embedded (bitmap) font. */ int pdf_begin_char_proc(P8(gx_device_pdf * pdev, int w, int h, int x_width, int y_offset, gs_id id, pdf_char_proc_t **ppcp, pdf_stream_position_t * ppos)); /* End a CharProc. */ int pdf_end_char_proc(P2(gx_device_pdf * pdev, pdf_stream_position_t * ppos)); /* Put out a reference to an image as a character in an embedded font. */ int pdf_do_char_image(P3(gx_device_pdf * pdev, const pdf_char_proc_t * pcp, const gs_matrix * pimat)); /* ---------------- Exported by gdevpdfs.c for gdevpdft.c ---------------- */ /* ---------------- Exported by gdevpdff.c ---------------- */ typedef struct pdf_standard_font_s { const char *fname; gs_encoding_index_t base_encoding; } pdf_standard_font_t; extern const pdf_standard_font_t pdf_standard_fonts[]; /* Return the index of a standard font name, or -1 if missing. */ int pdf_find_standard_font(P2(const byte *str, uint size)); /* * Compute and return the orig_matrix of a font. */ int pdf_font_orig_matrix(P2(const gs_font *font, gs_matrix *pmat)); /* * Find the original (unscaled) standard font corresponding to an * arbitrary font, if any. Return its index in standard_fonts, or -1. */ int pdf_find_orig_font(P3(gx_device_pdf *pdev, gs_font *font, gs_matrix *pfmat)); /* * Determine the embedding status of a font. If the font is in the base * 14, store its index (0..13) in *pindex and its similarity to the base * font (as determined by the font's same_font procedure) in *psame. */ pdf_font_embed_t pdf_font_embed_status(P4(gx_device_pdf *pdev, gs_font *font, int *pindex, int *psame)); /* * Determine the resource type (resourceFont or resourceCIDFont) for * a font. */ pdf_resource_type_t pdf_font_resource_type(P1(const gs_font *font)); /* * Allocate a font resource. If pfd != 0, a FontDescriptor is allocated, * with its id, values, and char_count taken from *pfd. * If font != 0, its FontType is used to determine whether the resource * is of type Font or of (pseudo-)type CIDFont; in this case, pfres->font * and pfres->FontType are also set. */ int pdf_alloc_font(P5(gx_device_pdf *pdev, gs_id rid, pdf_font_t **ppfres, const pdf_font_descriptor_t *pfd, gs_font *font)); /* * Create a new pdf_font for a gs_font. This procedure is only intended * to be called from one place in gdevpdft.c. */ int pdf_create_pdf_font(P4(gx_device_pdf *pdev, gs_font *font, const gs_matrix *pomat, pdf_font_t **pppf)); /* * Determine whether a font is a subset font by examining the name. */ bool pdf_has_subset_prefix(P2(const byte *str, uint size)); /* * Make the prefix for a subset font from the font's resource ID. */ void pdf_make_subset_prefix(P3(const gx_device_pdf *pdev, byte *str, ulong id)); /* * Adjust the FontName of a newly created FontDescriptor so that it is * unique if necessary. If the name was changed, return 1. */ int pdf_adjust_font_name(P3(const gx_device_pdf *pdev, pdf_font_descriptor_t *pfd, bool is_standard)); /* Add an encoding difference to a font. */ int pdf_add_encoding_difference(P5(gx_device_pdf *pdev, pdf_font_t *ppf, int chr, gs_font_base *bfont, gs_glyph glyph)); /* * Get the width of a given character in a (base) font. May add the width * to the widths cache (ppf->Widths). */ int pdf_char_width(P4(pdf_font_t *ppf, int ch, gs_font *font, int *pwidth /* may be NULL */)); /* * Get the width of a glyph in a (base) font. Return 1 if the width should * not be cached. */ int pdf_glyph_width(P4(pdf_font_t *ppf, gs_glyph glyph, gs_font *font, int *pwidth /* must not be NULL */)); /* * Find the range of character codes that includes all the defined * characters in a font. */ void pdf_find_char_range(P3(gs_font *font, int *pfirst, int *plast)); /* Compute the FontDescriptor for a font or a font subset. */ int pdf_compute_font_descriptor(P4(gx_device_pdf *pdev, pdf_font_descriptor_t *pfd, gs_font *font, const byte *used /*[32]*/)); /* Unregister the standard fonts when cleaning up. */ void pdf_unregister_fonts(P1(gx_device_pdf *pdev)); /* ---------------- Exported by gdevpdfw.c ---------------- */ /* Register a font for eventual writing (embedded or not). */ int pdf_register_font(P3(gx_device_pdf *pdev, gs_font *font, pdf_font_t *ppf)); /* Write out the font resources when wrapping up the output. */ int pdf_write_font_resources(P1(gx_device_pdf *pdev)); /* * Write a font descriptor. * (Exported only for gdevpdfe.c.) */ int pdf_write_FontDescriptor(P2(gx_device_pdf *pdev, const pdf_font_descriptor_t *pfd)); /* * Write CIDSystemInfo for a CIDFont or CMap. * (Exported only for gdevpdff.c.) */ int pdf_write_CIDFont_system_info(P2(gx_device_pdf *pdev, const gs_font *pcidfont)); #ifndef gs_cmap_DEFINED # define gs_cmap_DEFINED typedef struct gs_cmap_s gs_cmap_t; #endif int pdf_write_CMap_system_info(P2(gx_device_pdf *pdev, const gs_cmap_t *pcmap)); /* ---------------- Exported by gdevpdfe.c ---------------- */ /* * Write the FontDescriptor and FontFile* data for an embedded font. * Return a rangecheck error if the font can't be embedded. * (Exported only for gdevpdfw.c.) */ int pdf_write_embedded_font(P2(gx_device_pdf *pdev, pdf_font_descriptor_t *pfd)); #endif /* gdevpdff_INCLUDED */