1 /* Copyright (C) 2001-2012 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,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
13    CA  94903, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* Driver interface for text */
18 
19 #ifndef gstext_INCLUDED
20 #  define gstext_INCLUDED
21 
22 #include "gsccode.h"
23 #include "gscpm.h"
24 
25 /*
26  * Note that text display must return information to the generic code:
27  *	If TEXT_RETURN_WIDTH or TEXT_DO_CHARWIDTH, the string escapement
28  *	  (a.k.a. "width");
29  *	If TEXT_DO_*_CHARPATH, the entire character description;
30  *	If TEXT_DO_*_CHARBOXPATH, the character bounding box.
31  */
32 
33 /*
34  * Define the set of possible text operations.  While we define this as
35  * a bit mask for convenience in testing, only certain combinations are
36  * meaningful.  Specifically, the following are errors:
37  *      - No FROM or DO.
38  *      - More than one FROM or DO.
39  *	- FROM_SINGLE with size != 1.
40  *      - Both ADD_TO and REPLACE.
41  */
42 #define TEXT_HAS_MORE_THAN_ONE_(op, any)\
43   ( ((op) & any) & (((op) & any) - 1) )
44 #define TEXT_OPERATION_IS_INVALID(op)\
45   (!((op) & TEXT_FROM_ANY) ||\
46    !((op) & TEXT_DO_ANY) ||\
47    TEXT_HAS_MORE_THAN_ONE_(op, TEXT_FROM_ANY) ||\
48    TEXT_HAS_MORE_THAN_ONE_(op, TEXT_DO_ANY) ||\
49    (((op) & TEXT_ADD_ANY) && ((op) & TEXT_REPLACE_WIDTHS))\
50    )
51 #define TEXT_PARAMS_ARE_INVALID(params)\
52   (TEXT_OPERATION_IS_INVALID((params)->operation) ||\
53    ( ((params)->operation & TEXT_FROM_ANY_SINGLE) && ((params)->size != 1) )\
54    )
55 
56         /* Define the representation of the text itself. */
57 #define TEXT_FROM_STRING          0x00001
58 #define TEXT_FROM_BYTES           0x00002
59 #define TEXT_FROM_CHARS           0x00004
60 #define TEXT_FROM_GLYPHS          0x00008
61 #define TEXT_FROM_SINGLE_CHAR     0x00010
62 #define TEXT_FROM_SINGLE_GLYPH    0x00020
63 #define TEXT_FROM_ANY_SINGLE	/* only for testing and masking */\
64   (TEXT_FROM_SINGLE_CHAR | TEXT_FROM_SINGLE_GLYPH)
65 #define TEXT_FROM_ANY	/* only for testing and masking */\
66   (TEXT_FROM_STRING | TEXT_FROM_BYTES | TEXT_FROM_CHARS | TEXT_FROM_GLYPHS |\
67    TEXT_FROM_ANY_SINGLE)
68         /* Define how to compute escapements. */
69 #define TEXT_ADD_TO_ALL_WIDTHS    0x00040
70 #define TEXT_ADD_TO_SPACE_WIDTH   0x00080
71 #define TEXT_ADD_ANY	/* only for testing and masking */\
72   (TEXT_ADD_TO_ALL_WIDTHS | TEXT_ADD_TO_SPACE_WIDTH)
73 #define TEXT_REPLACE_WIDTHS       0x00100
74         /* Define what result should be produced. */
75 #define TEXT_DO_NONE              0x00200	/* stringwidth or cshow only */
76 #define TEXT_DO_DRAW              0x00400
77 #define TEXT_DO_CHARWIDTH         0x00800	/* rmoveto by width */
78 #define TEXT_DO_FALSE_CHARPATH    0x01000
79 #define TEXT_DO_TRUE_CHARPATH     0x02000
80 #define TEXT_DO_FALSE_CHARBOXPATH 0x04000
81 #define TEXT_DO_TRUE_CHARBOXPATH  0x08000
82 #define TEXT_DO_ANY_CHARPATH	/* only for testing and masking */\
83   (TEXT_DO_CHARWIDTH | TEXT_DO_FALSE_CHARPATH | TEXT_DO_TRUE_CHARPATH |\
84    TEXT_DO_FALSE_CHARBOXPATH | TEXT_DO_TRUE_CHARBOXPATH)
85 #define TEXT_DO_ANY	/* only for testing and masking */\
86   (TEXT_DO_NONE | TEXT_DO_DRAW | TEXT_DO_ANY_CHARPATH)
87         /* Define whether the client intervenes between characters. */
88 #define TEXT_INTERVENE            0x10000
89         /* Define whether to return the width. */
90 #define TEXT_RETURN_WIDTH         0x20000
91         /* PDF mode "3 Tr" */
92 #define TEXT_RENDER_MODE_3        0x40000
93 
94 /*
95  * Define the structure of parameters passed in for text display.
96  * Note that the implementation does not modify any of these; the client
97  * must not modify them after initialization.
98  */
99 typedef struct gs_text_params_s {
100     /* The client must set the following in all cases. */
101     uint operation;		/* TEXT_xxx mask */
102     union sd_ {
103         const byte *bytes;	/* FROM_STRING, FROM_BYTES */
104         const gs_char *chars;	/* FROM_CHARS */
105         const gs_glyph *glyphs;	/* FROM_GLYPHS */
106         gs_char d_char;		/* FROM_SINGLE_CHAR */
107         gs_glyph d_glyph;	/* FROM_SINGLE_GLYPH */
108     } data;
109     uint size;			/* number of data elements, */
110                                 /* must be 1 if FROM_SINGLE */
111     /* The following are used only in the indicated cases. */
112     gs_point delta_all;		/* ADD_TO_ALL_WIDTHS */
113     gs_point delta_space;	/* ADD_TO_SPACE_WIDTH */
114     union s_ {
115         gs_char s_char;		/* ADD_TO_SPACE_WIDTH & !FROM_GLYPHS */
116         gs_glyph s_glyph;	/* ADD_TO_SPACE_WIDTH & FROM_GLYPHS */
117     } space;
118     /*
119      * If x_widths == y_widths, widths are taken in pairs; note that in this
120      * case, widths_size is the number of widths, not the number of pairs.
121      * Either one may be NULL, meaning widths = 0.
122      */
123     const float *x_widths;	/* REPLACE_WIDTHS */
124     const float *y_widths;	/* REPLACE_WIDTHS */
125     uint widths_size;		/* REPLACE_WIDTHS */
126 } gs_text_params_t;
127 
128 #define st_gs_text_params_max_ptrs 3
129 /*extern_st(st_gs_text_params); */
130 #define public_st_gs_text_params() /* in gstext.c */\
131   gs_public_st_composite(st_gs_text_params, gs_text_params_t,\
132     "gs_text_params", text_params_enum_ptrs, text_params_reloc_ptrs)
133 
134 /* Assuming REPLACE_WIDTHS is set, return the width of the i'th character. */
135 int gs_text_replaced_width(const gs_text_params_t *text, uint index,
136                            gs_point *pwidth);
137 
138 /*
139  * Define the abstract type for the structure that tracks the state of text
140  * processing.
141  */
142 #ifndef gs_text_enum_DEFINED
143 #  define gs_text_enum_DEFINED
144 typedef struct gs_text_enum_s gs_text_enum_t;
145 #endif
146 
147 /* Abstract types */
148 #ifndef gx_device_DEFINED
149 #  define gx_device_DEFINED
150 typedef struct gx_device_s gx_device;
151 #endif
152 #ifndef gs_imager_state_DEFINED
153 #  define gs_imager_state_DEFINED
154 typedef struct gs_imager_state_s gs_imager_state;
155 #endif
156 #ifndef gx_device_color_DEFINED
157 #  define gx_device_color_DEFINED
158 typedef struct gx_device_color_s gx_device_color;
159 #endif
160 #ifndef gs_font_DEFINED
161 #  define gs_font_DEFINED
162 typedef struct gs_font_s gs_font;
163 #endif
164 #ifndef gx_path_DEFINED
165 #  define gx_path_DEFINED
166 typedef struct gx_path_s gx_path;
167 #endif
168 #ifndef gx_clip_path_DEFINED
169 #  define gx_clip_path_DEFINED
170 typedef struct gx_clip_path_s gx_clip_path;
171 #endif
172 
173 /*
174  * Define the driver procedure for text.  This procedure must allocate
175  * the enumerator (see gxtext.h) and initialize the procs and rc members.
176  */
177 #define dev_t_proc_text_begin(proc, dev_t)\
178   int proc(dev_t *dev,\
179     gs_imager_state *pis,\
180     const gs_text_params_t *text,\
181     gs_font *font,\
182     gx_path *path,			/* unless DO_NONE */\
183     const gx_device_color *pdcolor,	/* if DO_DRAW */\
184     const gx_clip_path *pcpath,		/* if DO_DRAW */\
185     gs_memory_t *memory,\
186     gs_text_enum_t **ppte)
187 #define dev_proc_text_begin(proc)\
188   dev_t_proc_text_begin(proc, gx_device)
189 
190 /*
191  * Begin processing text.  This calls the device procedure, and also
192  * initializes the common parts of the enumerator.
193  */
194 dev_proc_text_begin(gx_device_text_begin);
195 
196 /* Begin processing text with a graphics state. */
197 #ifndef gs_state_DEFINED
198 #  define gs_state_DEFINED
199 typedef struct gs_state_s gs_state;
200 #endif
201 int gs_text_begin(gs_state * pgs, const gs_text_params_t * text,
202                   gs_memory_t * mem, gs_text_enum_t ** ppenum);
203 
204 /*
205  * Update the device color to be used with text (because a kshow or
206  * cshow procedure may have changed the current color).
207  */
208 int gs_text_update_dev_color(gs_state * pgs, gs_text_enum_t * pte);
209 
210 /* Begin the PostScript-equivalent text operators. */
211 int
212 gs_show_begin(gs_state *, const byte *, uint,
213               gs_memory_t *, gs_text_enum_t **),
214     gs_ashow_begin(gs_state *, floatp, floatp, const byte *, uint,
215                    gs_memory_t *, gs_text_enum_t **),
216     gs_widthshow_begin(gs_state *, floatp, floatp, gs_char,
217                        const byte *, uint,
218                        gs_memory_t *, gs_text_enum_t **),
219     gs_awidthshow_begin(gs_state *, floatp, floatp, gs_char,
220                         floatp, floatp, const byte *, uint,
221                         gs_memory_t *, gs_text_enum_t **),
222     gs_kshow_begin(gs_state *, const byte *, uint,
223                    gs_memory_t *, gs_text_enum_t **),
224     gs_xyshow_begin(gs_state *, const byte *, uint,
225                     const float *, const float *, uint,
226                     gs_memory_t *, gs_text_enum_t **),
227     gs_glyphshow_begin(gs_state *, gs_glyph,
228                        gs_memory_t *, gs_text_enum_t **),
229     gs_cshow_begin(gs_state *, const byte *, uint,
230                    gs_memory_t *, gs_text_enum_t **),
231     gs_stringwidth_begin(gs_state *, const byte *, uint,
232                          gs_memory_t *, gs_text_enum_t **),
233     gs_charpath_begin(gs_state *, const byte *, uint, bool,
234                       gs_memory_t *, gs_text_enum_t **),
235     gs_glyphpath_begin(gs_state *, gs_glyph, bool,
236                        gs_memory_t *, gs_text_enum_t **),
237     gs_glyphwidth_begin(gs_state *, gs_glyph,
238                         gs_memory_t *, gs_text_enum_t **),
239     gs_charboxpath_begin(gs_state *, const byte *, uint, bool,
240                          gs_memory_t *, gs_text_enum_t **);
241 
242 /* Compute the number of characters in a text. */
243 int gs_text_size(gs_state * pgs, gs_text_params_t *text, gs_memory_t * mem);
244 /* Retrieve text params from enumerator. */
245 gs_text_params_t *gs_get_text_params(gs_text_enum_t *pte);
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