1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied, modified
8    or distributed except as expressly authorized under the terms of that
9    license.  Refer to licensing information at http://www.artifex.com/
10    or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11    San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12 */
13 
14 /* $Id: gdevpdtt.h 8265 2007-10-02 07:31:58Z ken $ */
15 /* Internal text processing interface for pdfwrite */
16 
17 #ifndef gdevpdtt_INCLUDED
18 #  define gdevpdtt_INCLUDED
19 
20 /*
21  * This file is only used internally to define the interface between
22  * gdevpdtt.c, gdevpdtc.c, and gdevpdte.c.
23  */
24 
25 /* ---------------- Coordinate systems ---------------- */
26 
27 /*
28 
29   The current text code has to deal with 6 different coordinate systems.
30   This situation is complex, confusing, and fragile, but despite literally
31   years of struggle we have been unable to understand how to simplify it.
32 
33   1) PostScript user space at the time a text operator is invoked.  The
34      width values for ashow, xshow, etc. are specified in this space: these
35      values appear in the delta_all, delta_space, x_widths, and y_widths
36      members of the text member of the common part of the text enumerator
37      (pdf_text_enum_t).
38 
39   2) Device space.  For the pdfwrite device, this is a straightforward space
40      with (0,0) in the lower left corner.  The usual resolution is 720 dpi,
41      but this is user-settable to provide a tradeoff between file size and
42      bitmap resolution (for rendered Patterns and fonts that have to be
43      converted to bitmaps).
44 
45   3) PDF user space.  During the processing of text operators, this is
46      always the same as the default PDF user space, in which 1 unit = 1/72",
47      because an Acrobat quirk apparently requires this.  (See stream_to_text
48      in gdevpdfu.c.)
49 
50   4) Font design space.  This is the space in which the font's character
51      outlines and advance widths are specified, including the width values
52      returned by font->procs.glyph_info and by pdf_char_widths.
53 
54   5) PDF unscaled text space.  This space is used for the PDF width
55      adjustment values (Tc, Tw, and TL parameters, and " operator) and
56      positioning coordinates (Td and TD operators).
57 
58   6) PDF text space.  This space is used for the width adjustments for the
59      TJ operator.
60 
61   The following convert between these spaces:
62 
63   - The PostScript CTM (pte->pis->ctm) maps #1 to #2.
64 
65   - The mapping from #3 to #2 is a scaling by pdev->HWResolution / 72.
66 
67   - The mapping from #5 to #6 is a scaling by the size member of
68     pdf_text_state_values_t, which is the size value for the Tf operator.
69 
70   - The matrix member of pdf_text_state_values_t maps #5 to #2, which is the
71     matrix for the Tm operator or its abbreviations.
72 
73   - The FontMatrix of a font maps #4 to #1.
74 
75   Note that the PDF text matrix (set by the Tm operator) maps #5 to #3.
76   However, this is not actually stored anywhere: it is computed by
77   multiplying the #5->#2 matrix by the #2->#3 scaling.
78 
79 */
80 
81 /* ---------------- Types and structures ---------------- */
82 
83 #ifndef pdf_char_glyph_pair_DEFINED
84 #  define pdf_char_glyph_pair_DEFINED
85 typedef struct pdf_char_glyph_pair_s pdf_char_glyph_pair_t;
86 #endif
87 
88 #ifndef pdf_char_glyph_pairs_DEFINED
89 #  define pdf_char_glyph_pairs_DEFINED
90 typedef struct pdf_char_glyph_pairs_s pdf_char_glyph_pairs_t;
91 #endif
92 
93 /* Define a structure for a text characters list. */
94 /* It must not contain pointers due to variable length. */
95 struct pdf_char_glyph_pairs_s {
96     int num_all_chars;
97     int num_unused_chars;
98     int unused_offset;  /* The origin of the unused character table.*/
99     pdf_char_glyph_pair_t s[1];  /* Variable length. */
100 };
101 
102 /* Define the text enumerator. */
103 typedef struct pdf_text_enum_s {
104     gs_text_enum_common;
105     gs_text_enum_t *pte_default;
106     gs_fixed_point origin;
107     bool charproc_accum;
108     bool cdevproc_callout;
109     double cdevproc_result[10];
110     pdf_char_glyph_pairs_t *cgp;
111     gs_char output_char_code;
112 } pdf_text_enum_t;
113 #define private_st_pdf_text_enum()\
114   extern_st(st_gs_text_enum);\
115   gs_private_st_suffix_add2(st_pdf_text_enum, pdf_text_enum_t,\
116     "pdf_text_enum_t", pdf_text_enum_enum_ptrs, pdf_text_enum_reloc_ptrs,\
117     st_gs_text_enum, pte_default, cgp)
118 
119 /*
120  * Define quantities derived from the current font and CTM, used within
121  * the text processing loop.  NOTE: This structure has no GC descriptor
122  * and must therefore only be used locally (allocated on the C stack).
123  */
124 typedef struct pdf_text_process_state_s {
125     pdf_text_state_values_t values;
126     gs_font *font;
127 } pdf_text_process_state_t;
128 
129 /*
130  * Define the structure used to return glyph width information.  Note that
131  * there are two different sets of width information: real-number (x,y)
132  * values, which give the true advance width, and an integer value, which
133  * gives an X advance width for WMode = 0 or a Y advance width for WMode = 1.
134  * The return value from pdf_glyph_width() indicates which of these is/are
135  * valid.
136  */
137 typedef struct pdf_glyph_width_s {
138     double w;
139     gs_point xy;
140     gs_point v;				/* glyph origin shift */
141 } pdf_glyph_width_t;
142 typedef struct pdf_glyph_widths_s {
143     pdf_glyph_width_t Width;		/* unmodified, for Widths */
144     pdf_glyph_width_t real_width;	/* possibly modified, for rendering */
145     bool replaced_v;
146 } pdf_glyph_widths_t;
147 
148 /* ---------------- Procedures ---------------- */
149 
150 /*
151  * Declare the procedures for processing different species of text.
152  * These procedures may, but need not, copy pte->text into buf
153  * (a caller-supplied buffer large enough to hold the string).
154  */
155 #define PROCESS_TEXT_PROC(proc)\
156   int proc(gs_text_enum_t *pte, void *vbuf, uint bsize)
157 
158 /* ------ gdevpdtt.c ------ */
159 
160 /*
161  * Compute and return the orig_matrix of a font.
162  */
163 int pdf_font_orig_matrix(const gs_font *font, gs_matrix *pmat);
164 
165 /*
166  * Check the Encoding compatibility
167  */
168 bool pdf_check_encoding_compatibility(const pdf_font_resource_t *pdfont,
169 		const pdf_char_glyph_pair_t *pairs, int num_chars);
170 
171 /*
172  * Create or find a font resource object for a text.
173  */
174 int
175 pdf_obtain_font_resource(pdf_text_enum_t *penum,
176 		const gs_string *pstr, pdf_font_resource_t **ppdfont);
177 
178 /*
179  * Create or find a font resource object for a glyphshow text.
180  */
181 int pdf_obtain_font_resource_unencoded(pdf_text_enum_t *penum,
182 	    const gs_string *pstr, pdf_font_resource_t **ppdfont, const gs_glyph *gdata);
183 
184 /*
185  * Create or find a CID font resource object for a glyph set.
186  */
187 int pdf_obtain_cidfont_resource(gx_device_pdf *pdev, gs_font *subfont,
188 			    pdf_font_resource_t **ppdsubf,
189 			    pdf_char_glyph_pairs_t *cgp);
190 
191 /*
192  * Create or find a parent Type 0 font resource object for a CID font resource.
193  */
194 int pdf_obtain_parent_type0_font_resource(gx_device_pdf *pdev, pdf_font_resource_t *pdsubf,
195 		uint font_index, const gs_const_string *CMapName, pdf_font_resource_t **pdfont);
196 
197 /*
198  * Retrive font resource attached to a font.
199  * allocating glyph_usage and real_widths on request.
200  */
201 int pdf_attached_font_resource(gx_device_pdf *pdev, gs_font *font,
202 			   pdf_font_resource_t **pdfont, byte **glyph_usage,
203 			   double **real_widths, int *num_chars, int *num_widths);
204 
205 /*
206  * Attach font resource to a font.
207  */
208 int pdf_attach_font_resource(gx_device_pdf *pdev, gs_font *font,
209 			 pdf_font_resource_t *pdfont);
210 
211 /*
212  * Locate a font cache element.
213  */
214 pdf_font_cache_elem_t **
215 pdf_locate_font_cache_elem(gx_device_pdf *pdev, gs_font *font);
216 
217 /*
218  * Create a font resource object for a gs_font of Type 3.
219  */
220 int pdf_make_font3_resource(gx_device_pdf *pdev, gs_font *font,
221 		       pdf_font_resource_t **ppdfont);
222 
223 /*
224  * Compute the cached values in the text processing state from the text
225  * parameters, pdfont, and pis->ctm.  Return either an error code (< 0) or a
226  * mask of operation attributes that the caller must emulate.  Currently the
227  * only such attributes are TEXT_ADD_TO_ALL_WIDTHS and
228  * TEXT_ADD_TO_SPACE_WIDTH.
229  */
230 int pdf_update_text_state(pdf_text_process_state_t *ppts,
231 			  const pdf_text_enum_t *penum,
232 			  pdf_font_resource_t *pdfont,
233 			  const gs_matrix *pfmat);
234 
235 /*
236  * Set up commands to make the output state match the processing state.
237  * General graphics state commands are written now; text state commands
238  * are written later.
239  */
240 int pdf_set_text_process_state(gx_device_pdf *pdev,
241 			       const gs_text_enum_t *pte, /*for pdcolor, pis*/
242 			       pdf_text_process_state_t *ppts);
243 
244 /*
245  * Get the widths (unmodified and possibly modified) of a glyph in a (base)
246  * font.  If the width is cachable (implying that the w values area valid),
247  * return 0; if only the xy values are valid, or the width is not cachable
248  * for some other reason, return 1.
249  * Return TEXT_PROCESS_CDEVPROC if a CDevProc callout is needed.
250  * cdevproc_result != NULL if we restart after a CDevProc callout.
251  */
252 int pdf_glyph_widths(pdf_font_resource_t *pdfont, int wmode, gs_glyph glyph,
253 		     gs_font *font, pdf_glyph_widths_t *pwidths,
254 		     const double cdevproc_result[10]);
255 
256 /*
257  * Fall back to the default text processing code when needed.
258  */
259 int pdf_default_text_begin(gs_text_enum_t *pte, const gs_text_params_t *text,
260 			   gs_text_enum_t **ppte);
261 
262 /*
263  * Check for simple font.
264  */
265 bool pdf_is_simple_font(gs_font *font);
266 
267 /*
268  * Check for CID font.
269  */
270 bool pdf_is_CID_font(gs_font *font);
271 
272 /* Release a text characters colloction. */
273 void pdf_text_release_cgp(pdf_text_enum_t *penum);
274 
275 /* Return char code by glyph. */
276 gs_char pdf_find_glyph(pdf_font_resource_t *pdfont, gs_glyph glyph);
277 
278 /* ------ gdevpdtc.c ------ */
279 
280 PROCESS_TEXT_PROC(process_composite_text);
281 PROCESS_TEXT_PROC(process_cmap_text);
282 PROCESS_TEXT_PROC(process_cid_text);
283 
284 /* ------ gdevpdte.c ------ */
285 
286 PROCESS_TEXT_PROC(process_plain_text);
287 
288 /*
289  * Process a string with a simple gs_font.
290  */
291 int pdf_process_string_aux(pdf_text_enum_t *penum, gs_string *pstr,
292 			      const gs_glyph *gdata, const gs_matrix *pfmat,
293 			      pdf_text_process_state_t *ppts);
294 
295 /*
296  * Emulate TEXT_ADD_TO_ALL_WIDTHS and/or TEXT_ADD_TO_SPACE_WIDTH,
297  * and implement TEXT_REPLACE_WIDTHS if requested.
298  * Uses and updates ppts->values.matrix; uses ppts->values.pdfont.
299  */
300 int process_text_modify_width(pdf_text_enum_t *pte, gs_font *font,
301 			  pdf_text_process_state_t *ppts,
302 			  const gs_const_string *pstr,
303 			  gs_point *pdpt, const gs_glyph *gdata, bool composite);
304 
305 /*
306  * Add char code pair to ToUnicode CMap,
307  * creating the CMap on neccessity.
308  */
309 int
310 pdf_add_ToUnicode(gx_device_pdf *pdev, gs_font *font, pdf_font_resource_t *pdfont,
311 		  gs_glyph glyph, gs_char ch, const gs_const_string *gnstr);
312 
313 /*
314  * Get character code from a glyph code.
315  * An usage of this function is very undesirable,
316  * because a glyph may be unlisted in Encoding.
317  */
318 int pdf_encode_glyph(gs_font_base *bfont, gs_glyph glyph0,
319 	    byte *buf, int buf_size, int *char_code_length);
320 
321 int pdf_shift_text_currentpoint(pdf_text_enum_t *penum, gs_point *wpt);
322 
323 void adjust_first_last_char(pdf_font_resource_t *pdfont, byte *str, int size);
324 
325 float pdf_calculate_text_size(gs_imager_state *pis, pdf_font_resource_t *pdfont,
326 			      const gs_matrix *pfmat, gs_matrix *smat, gs_matrix *tmat,
327 			      gs_font *font, gx_device_pdf *pdev);
328 #endif /* gdevpdtt_INCLUDED */
329