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