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