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