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