1 /* Copyright (C) 2001-2019 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., 1305 Grant Avenue - Suite 200, Novato, 13 CA 94945, U.S.A., +1(415)492-9861, for further information. 14 */ 15 16 17 /* Driver text interface implementation support */ 18 19 #ifndef gxtext_INCLUDED 20 # define gxtext_INCLUDED 21 22 #include "gstext.h" 23 #include "gsrefct.h" 24 #include "gxfixed.h" 25 #include "gsfont.h" 26 #include "gxfcache.h" 27 28 /* Define the abstract type for the object procedures. */ 29 typedef struct gs_text_enum_procs_s gs_text_enum_procs_t; 30 31 /* 32 * Define values returned by text_process to the client. 33 */ 34 typedef struct gs_text_returned_s { 35 gs_char current_char; /* INTERVENE */ 36 gs_glyph current_glyph; /* INTERVENE */ 37 gs_point total_width; /* RETURN_WIDTH */ 38 } gs_text_returned_t; 39 40 /* 41 * Define the stack for composite fonts. 42 * If the current font is not composite, depth = -1. 43 * If the current font is composite, 0 <= depth <= MAX_FONT_STACK. 44 * items[0] through items[depth] are occupied. 45 * items[0].font is the root font. 46 * The root font must be composite, but may be of any map type. 47 * items[0..N-1] are modal composite fonts, for some N <= depth. 48 * items[N..depth-1] are non-modal composite fonts. 49 * items[depth] is a base font or a CIDFont (i.e. non-composite font). 50 * Note that if depth >= 0, the font member of the graphics state 51 * for a base font BuildChar/Glyph is the same as items[depth].font. 52 */ 53 #define MAX_FONT_STACK 5 54 typedef struct gx_font_stack_item_s { 55 gs_font *font; /* font at this level */ 56 uint index; /* if *font is a composite font, this is a font number of 57 selected discendant font (index in Encoding). 58 if *font is a CIDFont, an index of selected FDArray font. 59 zero otherwise. */ 60 } gx_font_stack_item_t; 61 typedef struct gx_font_stack_s { 62 int depth; 63 gx_font_stack_item_t items[1 + MAX_FONT_STACK]; 64 } gx_font_stack_t; 65 66 /* An enumeration object for string display. */ 67 typedef enum { 68 sws_none, 69 sws_cache, /* setcachedevice[2] */ 70 sws_no_cache, /* setcharwidth */ 71 sws_cache_width_only, /* setcharwidth for xfont char */ 72 sws_retry /* retry setcachedevice[2] */ 73 } show_width_status; 74 75 /* The types of memory and null devices may be opaque. */ 76 typedef struct gx_device_null_s gx_device_null; 77 78 /* 79 * Define the common part of the structure that tracks the state of text 80 * processing. All implementations of text_begin must allocate one of these 81 * using rc_alloc_struct_1; implementations may subclass and extend it. 82 * Note that it includes a copy of the text parameters. 83 * 84 * The freeing procedure (rc.free) must call rc_free_text_enum, which 85 * calls the enumerator's release procedure. This is required in order to 86 * properly decrement the reference count(s) of the referenced structures 87 * (in the common part of the structure, only the device). 88 */ 89 rc_free_proc(rc_free_text_enum); 90 #define gs_text_enum_common\ 91 /*\ 92 * The following copies of the arguments of text_begin are set at\ 93 * initialization, and const thereafter.\ 94 */\ 95 gs_text_params_t text; /* must be first for subclassing */\ 96 gx_device *dev;\ 97 gx_device *imaging_dev; /* see note below */\ 98 gs_gstate *pgs;\ 99 gs_font *orig_font;\ 100 gx_path *path; /* unless DO_NONE & !RETURN_WIDTH */\ 101 const gx_device_color *pdcolor; /* if DO_DRAW */\ 102 const gx_clip_path *pcpath; /* if DO_DRAW */\ 103 gs_memory_t *memory;\ 104 /* The following additional members are set at initialization. */\ 105 const gs_text_enum_procs_t *procs;\ 106 /* The following change dynamically. NOTE: gs_text_enum_copy_dynamic */\ 107 /* knows the entire list of dynamically changing elements. */\ 108 rc_header rc;\ 109 void *enum_client_data;\ 110 gs_font *current_font; /* changes for composite fonts */\ 111 gs_glyph outer_CID; /* When a Type 3 is a FMapType 9 descendent. */\ 112 bool is_pure_color; /* The text is painted with a pure color. */\ 113 gs_log2_scale_point log2_scale; /* for oversampling */\ 114 cached_fm_pair *pair; /* corresponds to the current_font and CTM*(1<<log2_scale) */\ 115 uint index; /* index within string */\ 116 uint xy_index; /* index within X/Y widths */\ 117 gx_font_stack_t fstack;\ 118 int cmap_code; /* hack for FMapType 9 composite fonts, */\ 119 /* the value returned by decode_next */\ 120 /* For pdf word spacing we must only apply the extra space for a single */\ 121 /* byte code of 32, not for a multi-byte code of 32. So, for example */ \ 122 /* not for character code <0020>. */ \ 123 bool single_byte_space; \ 124 /* We also need to know how many bytes of the string we used in order to */ \ 125 /* decode this character. So that we can tell if a space is <0020> or <20> */ \ 126 int bytes_decoded; \ 127 gs_point FontBBox_as_Metrics2; /* used with FontType 9,11 && WMode 1 */\ 128 ulong text_enum_id; /* debug purpose only - not used by algorythm. */\ 129 /* The following is controlled by a device. */\ 130 bool device_disabled_grid_fitting;\ 131 /* Following two members moved from the show enumerator */\ 132 gs_log2_scale_point fapi_log2_scale; /* scaling factors for oversampling with FAPI, -1 = not valid */\ 133 gs_point fapi_glyph_shift; /* glyph shift for FAPI-handled font */\ 134 /* The following are used to return information to the client. */\ 135 gs_text_returned_t returned; \ 136 /* Following are set at creation time */ \ 137 bool auto_release; /* true if old API, false if new */ \ 138 gs_gstate *pgs2; \ 139 int level; /* save the level of pgs */ \ 140 gs_char_path_mode charpath_flag; \ 141 gs_gstate *show_gstate; /* for setting pgs->show_gstate */ \ 142 /* at returns/callouts */ \ 143 int can_cache; /* -1 if can't use cache at all, */ \ 144 /* 0 if can read but not load, */ \ 145 /* 1 if can read and load */ \ 146 gs_int_rect ibox; /* int version of quick-check */ \ 147 /* (inner) clipping box */ \ 148 gs_int_rect obox; /* int version of (outer) clip box */ \ 149 int ftx, fty; /* transformed font translation */ \ 150 /* Following are updated dynamically */ \ 151 gs_glyph (*encode_char)(gs_font *, gs_char, gs_glyph_space_t); /* copied from font */ \ 152 gx_device_memory *dev_cache; /* cache device */ \ 153 gx_device_memory *dev_cache2; /* underlying alpha memory device, */ \ 154 /* if dev_cache is an alpha buffer */ \ 155 gx_device_null *dev_null; /* null device for stringwidth */ \ 156 /*uint index; */ /* index within string */ \ 157 /*uint xy_index;*/ /* index within X/Y widths */ \ 158 /*gs_char returned.current_char;*/ /* current char for render or move */ \ 159 /*gs_glyph returned.current_glyph;*/ /* current glyph ditto */ \ 160 gs_fixed_point wxy; /* width of current char in device coords */ \ 161 gs_point wxy_float; /* same for huge characters */ \ 162 bool use_wxy_float; \ 163 gs_fixed_point origin; /* unrounded origin of current char */ \ 164 /* in device coords, needed for */ \ 165 /* charpath and WMode=1 */ \ 166 cached_char *cc; /* being accumulated */ \ 167 /*gs_point returned.total_width;*/ /* total width of string, set at end */ \ 168 show_width_status width_status; \ 169 /*gs_log2_scale_point log2_scale;*/ \ 170 int (*continue_proc) (gs_show_enum *) /* continuation procedure */ 171 172 /* The typedef is in gstext.h. */ 173 struct gs_text_enum_s { 174 gs_text_enum_common; 175 }; 176 177 /* 178 * Notes on the imaging_dev field of device enumeration structures: 179 * 180 * This field is added as a hack to make the bbox device work 181 * correctly as a forwarding device in some cases, particularly the X 182 * driver. When the X driver is configured to use a memory device for 183 * rendering (ie the MaxBitmap parameter is large enough to hold the 184 * buffer), it sets up a pipeline where the bbox device forwards to 185 * the memory device. The bbox device is used to determine which areas 186 * of the buffer have been drawn on, so that the screen can be 187 * appropriately updated. 188 * 189 * This works well for low-level operations such as filling 190 * rectangles, because the bbox device can easily determine the bbox 191 * of the drawing operation before forwarding it to the target device. 192 * However, for higher level operations, such as those that require 193 * enumerators, the approach is fundamentally broken. Essentially, the 194 * execution of the drawing operation is the responsibility of the 195 * target device, and the bbox device doesn't really have any way to 196 * determine the bounding box. 197 * 198 * The approach taken here is to add an additional field to the 199 * enumerations, imaging_dev. In the common case where the target 200 * device implements the high level drawing operation in terms of 201 * lower level operations, setting the imaging_dev field to non-NULL 202 * requests that these lower level imaging operations be directed to 203 * the imaging_dev rather than dev. The bbox device sets the 204 * imaging_dev field to point to itself. Thus, the low level drawing 205 * operations are intercepted by the bbox device, so that the bbox is 206 * accounted for. 207 * 208 * Note that, if the target device implements higher level operations 209 * by itself, ie not by breaking it into lower level operations, this 210 * approach will fail. 211 */ 212 213 #define st_gs_text_enum_max_ptrs (st_gs_text_params_max_ptrs + 8) 214 /*extern_st(st_gs_text_enum); */ 215 #define public_st_gs_text_enum() /* in gstext.c */\ 216 gs_public_st_composite(st_gs_text_enum, gs_text_enum_t, "gs_text_enum_t",\ 217 text_enum_enum_ptrs, text_enum_reloc_ptrs) 218 219 /* 220 * Initialize a newly created text enumerator. Implementations of 221 * text_begin must call this just after allocating the enumerator. 222 * Note that this procedure can return an error, e.g., if attempting 223 * a glyph-based operation with a composite font. 224 */ 225 int gs_text_enum_init(gs_text_enum_t *pte, 226 const gs_text_enum_procs_t *procs, 227 gx_device *dev, gs_gstate *pgs, 228 const gs_text_params_t *text, 229 gs_font *font, gx_path *path, 230 const gx_device_color *pdcolor, 231 const gx_clip_path *pcpath, 232 gs_memory_t *mem); 233 234 /* Allocate a text enumerator. 235 * This is primarily intended for code avoiding the device API, such 236 * as that purely for retrieving metrics 237 */ 238 gs_text_enum_t * 239 gs_text_enum_alloc(gs_memory_t * mem, gs_gstate * pgs, client_name_t cname); 240 241 /* 242 * Copy the dynamically changing elements from one enumerator to another. 243 * This is useful primarily for enumerators that sometimes pass the 244 * operation to a subsidiary enumerator. Note that `returned' is copied 245 * iff for_return is true. 246 */ 247 void gs_text_enum_copy_dynamic(gs_text_enum_t *pto, 248 const gs_text_enum_t *pfrom, 249 bool for_return); 250 251 /* 252 * Define some convenience macros for testing aspects of a text 253 * enumerator. 254 */ 255 256 #define SHOW_IS(penum, op_mask)\ 257 (((penum)->text.operation & (op_mask)) != 0) 258 #define SHOW_IS_ALL_OF(penum, op_mask)\ 259 (((penum)->text.operation & (op_mask)) == (op_mask)) 260 /* 261 * The comments next to the following macros indicate the 262 * corresponding test on gs_show_enum structures in pre-5.24 filesets. 263 */ 264 #define SHOW_IS_ADD_TO_ALL(penum) /* add */\ 265 SHOW_IS(penum, TEXT_ADD_TO_ALL_WIDTHS) 266 #define SHOW_IS_ADD_TO_SPACE(penum) /* wchr != no_char */\ 267 SHOW_IS(penum, TEXT_ADD_TO_SPACE_WIDTH) 268 #define SHOW_IS_DO_KERN(penum) /* do_kern */\ 269 SHOW_IS(penum, TEXT_INTERVENE) 270 #define SHOW_IS_SLOW(penum) /* slow_show */\ 271 SHOW_IS(penum, TEXT_REPLACE_WIDTHS | TEXT_ADD_TO_ALL_WIDTHS | TEXT_ADD_TO_SPACE_WIDTH | TEXT_INTERVENE) 272 #define SHOW_IS_DRAWING(penum) /* !stringwidth_flag */\ 273 !SHOW_IS(penum, TEXT_DO_NONE) 274 #define SHOW_IS_STRINGWIDTH(penum) /* stringwidth_flag > 0 */\ 275 SHOW_IS_ALL_OF(penum, TEXT_DO_NONE | TEXT_RETURN_WIDTH) 276 277 /* 278 * Define the procedures associated with text processing. 279 */ 280 struct gs_text_enum_procs_s { 281 282 /* 283 * Resync processing from an enumerator that may have different 284 * parameters and may be partway through processing the string. Note 285 * that this may only be implemented for certain kinds of changes, and 286 * will fail for other kinds. (We may reconsider this.) We require 287 * pfrom != pte. 288 */ 289 290 #define text_enum_proc_resync(proc)\ 291 int proc(gs_text_enum_t *pte, const gs_text_enum_t *pfrom) 292 293 text_enum_proc_resync((*resync)); 294 295 /* 296 * Process the text. The client should call this repeatedly until 297 * it returns <= 0. (> 0 means the client must take action: see 298 * gstext.h.) 299 * 300 * Note that a default implementation of this procedure can't simply do 301 * nothing and return: 302 * 303 * - If TEXT_DO_CHARWIDTH or TEXT_DO_*PATH is set, the procedure must 304 * append the appropriate elements to the path. 305 * 306 * - If TEXT_INTERVENE is set, the procedure must return to the client 307 * after each character except the last one in the string, setting 308 * returned.current_char and returned.current_glyph appropriately; 309 * also, it must reset the current font in the graphics state to its 310 * original value each time each time (after the first) that the 311 * procedure is called to process further characters of the string. 312 * 313 * - If TEXT_RETURN_WIDTH is set, the procedure must set 314 * returned.total_width when(ever) it returns. 315 * 316 * We should provide a default implementation that makes all these 317 * things simple, but currently we don't. 318 */ 319 320 #define text_enum_proc_process(proc)\ 321 int proc(gs_text_enum_t *pte) 322 323 text_enum_proc_process((*process)); 324 325 /* 326 * After the implementation returned TEXT_PROCESS_RENDER, determine 327 * whether it needs the entire character description, or only the width 328 * (escapement). 329 */ 330 331 #define text_enum_proc_is_width_only(proc)\ 332 bool proc(const gs_text_enum_t *pte) 333 334 text_enum_proc_is_width_only((*is_width_only)); 335 336 /* 337 * Return the width of the current character (in user space coordinates). 338 */ 339 340 #define text_enum_proc_current_width(proc)\ 341 int proc(const gs_text_enum_t *pte, gs_point *pwidth) 342 343 text_enum_proc_current_width((*current_width)); 344 345 /* 346 * Set the character width and optionally the bounding box, 347 * and optionally enable caching. 348 */ 349 350 #define text_enum_proc_set_cache(proc)\ 351 int proc(gs_text_enum_t *pte, const double *values,\ 352 gs_text_cache_control_t control) 353 354 text_enum_proc_set_cache((*set_cache)); 355 356 /* 357 * Prepare to retry processing the current character by uninstalling the 358 * cache device. 359 */ 360 361 #define text_enum_proc_retry(proc)\ 362 int proc(gs_text_enum_t *pte) 363 364 text_enum_proc_retry((*retry)); 365 366 /* 367 * Release the contents of the structure at the end of processing, 368 * but don't free the structure itself. (gs_text_release also does 369 * the latter.) 370 */ 371 372 #define text_enum_proc_release(proc)\ 373 void proc(gs_text_enum_t *pte, client_name_t cname) 374 375 text_enum_proc_release((*release)); 376 377 }; 378 379 /* Define the default release procedure. */ 380 text_enum_proc_release(gx_default_text_release); 381 382 #endif /* gxtext_INCLUDED */ 383