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: gstext.h 8470 2007-12-31 22:46:50Z alexcher $ */
15 /* Driver interface for text */
16 
17 #ifndef gstext_INCLUDED
18 #  define gstext_INCLUDED
19 
20 #include "gsccode.h"
21 #include "gscpm.h"
22 
23 /*
24  * Note that text display must return information to the generic code:
25  *	If TEXT_RETURN_WIDTH or TEXT_DO_CHARWIDTH, the string escapement
26  *	  (a.k.a. "width");
27  *	If TEXT_DO_*_CHARPATH, the entire character description;
28  *	If TEXT_DO_*_CHARBOXPATH, the character bounding box.
29  */
30 
31 /*
32  * Define the set of possible text operations.  While we define this as
33  * a bit mask for convenience in testing, only certain combinations are
34  * meaningful.  Specifically, the following are errors:
35  *      - No FROM or DO.
36  *      - More than one FROM or DO.
37  *	- FROM_SINGLE with size != 1.
38  *      - Both ADD_TO and REPLACE.
39  */
40 #define TEXT_HAS_MORE_THAN_ONE_(op, any)\
41   ( ((op) & any) & (((op) & any) - 1) )
42 #define TEXT_OPERATION_IS_INVALID(op)\
43   (!((op) & TEXT_FROM_ANY) ||\
44    !((op) & TEXT_DO_ANY) ||\
45    TEXT_HAS_MORE_THAN_ONE_(op, TEXT_FROM_ANY) ||\
46    TEXT_HAS_MORE_THAN_ONE_(op, TEXT_DO_ANY) ||\
47    (((op) & TEXT_ADD_ANY) && ((op) & TEXT_REPLACE_WIDTHS))\
48    )
49 #define TEXT_PARAMS_ARE_INVALID(params)\
50   (TEXT_OPERATION_IS_INVALID((params)->operation) ||\
51    ( ((params)->operation & TEXT_FROM_ANY_SINGLE) && ((params)->size != 1) )\
52    )
53 
54 	/* Define the representation of the text itself. */
55 #define TEXT_FROM_STRING          0x00001
56 #define TEXT_FROM_BYTES           0x00002
57 #define TEXT_FROM_CHARS           0x00004
58 #define TEXT_FROM_GLYPHS          0x00008
59 #define TEXT_FROM_SINGLE_CHAR     0x00010
60 #define TEXT_FROM_SINGLE_GLYPH    0x00020
61 #define TEXT_FROM_ANY_SINGLE	/* only for testing and masking */\
62   (TEXT_FROM_SINGLE_CHAR | TEXT_FROM_SINGLE_GLYPH)
63 #define TEXT_FROM_ANY	/* only for testing and masking */\
64   (TEXT_FROM_STRING | TEXT_FROM_BYTES | TEXT_FROM_CHARS | TEXT_FROM_GLYPHS |\
65    TEXT_FROM_ANY_SINGLE)
66 	/* Define how to compute escapements. */
67 #define TEXT_ADD_TO_ALL_WIDTHS    0x00040
68 #define TEXT_ADD_TO_SPACE_WIDTH   0x00080
69 #define TEXT_ADD_ANY	/* only for testing and masking */\
70   (TEXT_ADD_TO_ALL_WIDTHS | TEXT_ADD_TO_SPACE_WIDTH)
71 #define TEXT_REPLACE_WIDTHS       0x00100
72 	/* Define what result should be produced. */
73 #define TEXT_DO_NONE              0x00200	/* stringwidth or cshow only */
74 #define TEXT_DO_DRAW              0x00400
75 #define TEXT_DO_CHARWIDTH         0x00800	/* rmoveto by width */
76 #define TEXT_DO_FALSE_CHARPATH    0x01000
77 #define TEXT_DO_TRUE_CHARPATH     0x02000
78 #define TEXT_DO_FALSE_CHARBOXPATH 0x04000
79 #define TEXT_DO_TRUE_CHARBOXPATH  0x08000
80 #define TEXT_DO_ANY_CHARPATH	/* only for testing and masking */\
81   (TEXT_DO_CHARWIDTH | TEXT_DO_FALSE_CHARPATH | TEXT_DO_TRUE_CHARPATH |\
82    TEXT_DO_FALSE_CHARBOXPATH | TEXT_DO_TRUE_CHARBOXPATH)
83 #define TEXT_DO_ANY	/* only for testing and masking */\
84   (TEXT_DO_NONE | TEXT_DO_DRAW | TEXT_DO_ANY_CHARPATH)
85 	/* Define whether the client intervenes between characters. */
86 #define TEXT_INTERVENE            0x10000
87 	/* Define whether to return the width. */
88 #define TEXT_RETURN_WIDTH         0x20000
89 	/* PDF mode "3 Tr" */
90 #define TEXT_RENDER_MODE_3        0x40000
91 
92 /*
93  * Define the structure of parameters passed in for text display.
94  * Note that the implementation does not modify any of these; the client
95  * must not modify them after initialization.
96  */
97 typedef struct gs_text_params_s {
98     /* The client must set the following in all cases. */
99     uint operation;		/* TEXT_xxx mask */
100     union sd_ {
101 	const byte *bytes;	/* FROM_STRING, FROM_BYTES */
102 	const gs_char *chars;	/* FROM_CHARS */
103 	const gs_glyph *glyphs;	/* FROM_GLYPHS */
104 	gs_char d_char;		/* FROM_SINGLE_CHAR */
105 	gs_glyph d_glyph;	/* FROM_SINGLE_GLYPH */
106     } data;
107     uint size;			/* number of data elements, */
108 				/* must be 1 if FROM_SINGLE */
109     /* The following are used only in the indicated cases. */
110     gs_point delta_all;		/* ADD_TO_ALL_WIDTHS */
111     gs_point delta_space;	/* ADD_TO_SPACE_WIDTH */
112     union s_ {
113 	gs_char s_char;		/* ADD_TO_SPACE_WIDTH & !FROM_GLYPHS */
114 	gs_glyph s_glyph;	/* ADD_TO_SPACE_WIDTH & FROM_GLYPHS */
115     } space;
116     /*
117      * If x_widths == y_widths, widths are taken in pairs; note that in this
118      * case, widths_size is the number of widths, not the number of pairs.
119      * Either one may be NULL, meaning widths = 0.
120      */
121     const float *x_widths;	/* REPLACE_WIDTHS */
122     const float *y_widths;	/* REPLACE_WIDTHS */
123     uint widths_size;		/* REPLACE_WIDTHS */
124 } gs_text_params_t;
125 
126 #define st_gs_text_params_max_ptrs 3
127 /*extern_st(st_gs_text_params); */
128 #define public_st_gs_text_params() /* in gstext.c */\
129   gs_public_st_composite(st_gs_text_params, gs_text_params_t,\
130     "gs_text_params", text_params_enum_ptrs, text_params_reloc_ptrs)
131 
132 /* Assuming REPLACE_WIDTHS is set, return the width of the i'th character. */
133 int gs_text_replaced_width(const gs_text_params_t *text, uint index,
134 			   gs_point *pwidth);
135 
136 /*
137  * Define the abstract type for the structure that tracks the state of text
138  * processing.
139  */
140 #ifndef gs_text_enum_DEFINED
141 #  define gs_text_enum_DEFINED
142 typedef struct gs_text_enum_s gs_text_enum_t;
143 #endif
144 
145 /* Abstract types */
146 #ifndef gx_device_DEFINED
147 #  define gx_device_DEFINED
148 typedef struct gx_device_s gx_device;
149 #endif
150 #ifndef gs_imager_state_DEFINED
151 #  define gs_imager_state_DEFINED
152 typedef struct gs_imager_state_s gs_imager_state;
153 #endif
154 #ifndef gx_device_color_DEFINED
155 #  define gx_device_color_DEFINED
156 typedef struct gx_device_color_s gx_device_color;
157 #endif
158 #ifndef gs_font_DEFINED
159 #  define gs_font_DEFINED
160 typedef struct gs_font_s gs_font;
161 #endif
162 #ifndef gx_path_DEFINED
163 #  define gx_path_DEFINED
164 typedef struct gx_path_s gx_path;
165 #endif
166 #ifndef gx_clip_path_DEFINED
167 #  define gx_clip_path_DEFINED
168 typedef struct gx_clip_path_s gx_clip_path;
169 #endif
170 
171 /*
172  * Define the driver procedure for text.  This procedure must allocate
173  * the enumerator (see gxtext.h) and initialize the procs and rc members.
174  */
175 #define dev_t_proc_text_begin(proc, dev_t)\
176   int proc(dev_t *dev,\
177     gs_imager_state *pis,\
178     const gs_text_params_t *text,\
179     gs_font *font,\
180     gx_path *path,			/* unless DO_NONE */\
181     const gx_device_color *pdcolor,	/* if DO_DRAW */\
182     const gx_clip_path *pcpath,		/* if DO_DRAW */\
183     gs_memory_t *memory,\
184     gs_text_enum_t **ppte)
185 #define dev_proc_text_begin(proc)\
186   dev_t_proc_text_begin(proc, gx_device)
187 
188 /*
189  * Begin processing text.  This calls the device procedure, and also
190  * initializes the common parts of the enumerator.
191  */
192 dev_proc_text_begin(gx_device_text_begin);
193 
194 /* Begin processing text with a graphics state. */
195 #ifndef gs_state_DEFINED
196 #  define gs_state_DEFINED
197 typedef struct gs_state_s gs_state;
198 #endif
199 int gs_text_begin(gs_state * pgs, const gs_text_params_t * text,
200 		  gs_memory_t * mem, gs_text_enum_t ** ppenum);
201 
202 /*
203  * Update the device color to be used with text (because a kshow or
204  * cshow procedure may have changed the current color).
205  */
206 int gs_text_update_dev_color(gs_state * pgs, gs_text_enum_t * pte);
207 
208 
209 /* Begin the PostScript-equivalent text operators. */
210 int
211 gs_show_begin(gs_state *, const byte *, uint,
212 	      gs_memory_t *, gs_text_enum_t **),
213     gs_ashow_begin(gs_state *, floatp, floatp, const byte *, uint,
214 		   gs_memory_t *, gs_text_enum_t **),
215     gs_widthshow_begin(gs_state *, floatp, floatp, gs_char,
216 		       const byte *, uint,
217 		       gs_memory_t *, gs_text_enum_t **),
218     gs_awidthshow_begin(gs_state *, floatp, floatp, gs_char,
219 			floatp, floatp, const byte *, uint,
220 			gs_memory_t *, gs_text_enum_t **),
221     gs_kshow_begin(gs_state *, const byte *, uint,
222 		   gs_memory_t *, gs_text_enum_t **),
223     gs_xyshow_begin(gs_state *, const byte *, uint,
224 		    const float *, const float *, uint,
225 		    gs_memory_t *, gs_text_enum_t **),
226     gs_glyphshow_begin(gs_state *, gs_glyph,
227 		       gs_memory_t *, gs_text_enum_t **),
228     gs_cshow_begin(gs_state *, const byte *, uint,
229 		   gs_memory_t *, gs_text_enum_t **),
230     gs_stringwidth_begin(gs_state *, const byte *, uint,
231 			 gs_memory_t *, gs_text_enum_t **),
232     gs_charpath_begin(gs_state *, const byte *, uint, bool,
233 		      gs_memory_t *, gs_text_enum_t **),
234     gs_glyphpath_begin(gs_state *, gs_glyph, bool,
235 		       gs_memory_t *, gs_text_enum_t **),
236     gs_glyphwidth_begin(gs_state *, gs_glyph,
237 			gs_memory_t *, gs_text_enum_t **),
238     gs_charboxpath_begin(gs_state *, const byte *, uint, bool,
239 			 gs_memory_t *, gs_text_enum_t **);
240 
241 /* Compute the number of characters in a text. */
242 int gs_text_size(gs_state * pgs, gs_text_params_t *text, gs_memory_t * mem);
243 /* Retrieve text params from enumerator. */
244 gs_text_params_t *gs_get_text_params(gs_text_enum_t *pte);
245 
246 
247 /*
248  * Restart text processing with new parameters.
249  */
250 int gs_text_restart(gs_text_enum_t *pte, const gs_text_params_t *text);
251 
252 /*
253  * Resync text processing with new parameters and string position.
254  */
255 int gs_text_resync(gs_text_enum_t *pte, const gs_text_enum_t *pfrom);
256 
257 /*
258  * Define the possible return values from gs_text_process.  The client
259  * should call text_process until it returns 0 (successful completion) or a
260  * negative (error) value.
261  */
262 
263 	/*
264 	 * The client must render a character: obtain the code from
265 	 * gs_text_current_char/glyph, do whatever is necessary, and then
266 	 * call gs_text_process again.
267 	 */
268 #define TEXT_PROCESS_RENDER 1
269 
270 	/*
271 	 * The client has asked to intervene between characters.
272 	 * Obtain the current and next codes from gs_text_current_char/glyph
273 	 * and gs_text_next_char, do whatever is necessary, and then
274 	 * call gs_text_process again.
275 	 */
276 #define TEXT_PROCESS_INTERVENE 2
277 
278 	/*
279 	 * The device has asked to execute CDevProc.
280 	 * Obtain the current codes from gs_text_current_char/glyph,
281 	 * do whatever is necessary and put CDevProc results to pte->cdevproc_result,
282 	 * and then call gs_text_process again with pte->cdevproc_result_valid=true.
283 	 */
284 #define TEXT_PROCESS_CDEVPROC 3
285 
286 /* Process text after 'begin'. */
287 int gs_text_process(gs_text_enum_t *pte);
288 
289 /* Access elements of the enumerator. */
290 gs_font *gs_text_current_font(const gs_text_enum_t *pte);
291 gs_char gs_text_current_char(const gs_text_enum_t *pte);
292 gs_char gs_text_next_char(const gs_text_enum_t *pte);
293 gs_glyph gs_text_current_glyph(const gs_text_enum_t *pte);
294 int gs_text_total_width(const gs_text_enum_t *pte, gs_point *pwidth);
295 
296 /*
297  * After the implementation returned TEXT_PROCESS_RENDER, determine
298  * whether it needs the entire character description, or only the width
299  * (escapement).
300  */
301 bool gs_text_is_width_only(const gs_text_enum_t *pte);
302 
303 /*
304  * Return the width of the current character (in user space coordinates).
305  */
306 int gs_text_current_width(const gs_text_enum_t *pte, gs_point *pwidth);
307 
308 /*
309  * Set text metrics and optionally enable caching.  Return 1 iff the
310  * cache device was just installed.
311  */
312 typedef enum {
313     TEXT_SET_CHAR_WIDTH,	/* wx wy */
314     TEXT_SET_CACHE_DEVICE,	/* wx wy llx lly urx ury */
315     TEXT_SET_CACHE_DEVICE2	/* w0x w0y llx lly urx ury w1x w1y vx vy */
316 } gs_text_cache_control_t;
317 int
318     gs_text_set_cache(gs_text_enum_t *pte, const double *values,
319 		      gs_text_cache_control_t control),
320     gs_text_setcharwidth(gs_text_enum_t *pte, const double wxy[2]),
321     gs_text_setcachedevice(gs_text_enum_t *pte, const double wbox[6]),
322     gs_text_setcachedevice2(gs_text_enum_t *pte, const double wbox2[10]);
323 
324 /* Retry processing of the last character. */
325 int gs_text_retry(gs_text_enum_t *pte);
326 
327 /* Release the text processing structures. */
328 void gs_text_release(gs_text_enum_t *pte, client_name_t cname);
329 
330 /* Compute the number of characters in a text. */
331 int gs_text_count_chars(gs_state * pgs, gs_text_params_t *text, gs_memory_t * mem);
332 
333 #endif /* gstext_INCLUDED */
334