1 /* Copyright (C) 1992, 1995, 1997, 1999 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: gxfcache.h,v 1.27 2004/08/19 19:33:09 stefan Exp $ */ 18 /* Font and character cache definitions and procedures */ 19 /* Requires gsfont.h */ 20 21 #ifndef gxfcache_INCLUDED 22 # define gxfcache_INCLUDED 23 24 #include "gsccode.h" 25 #include "gsuid.h" 26 #include "gsxfont.h" 27 #include "gxbcache.h" 28 #include "gxfixed.h" 29 #include "gxftype.h" 30 31 /* ------ Font/matrix pair cache entry ------ */ 32 33 #ifndef gs_font_DEFINED 34 # define gs_font_DEFINED 35 typedef struct gs_font_s gs_font; 36 #endif 37 #ifndef cached_fm_pair_DEFINED 38 # define cached_fm_pair_DEFINED 39 typedef struct cached_fm_pair_s cached_fm_pair; 40 #endif 41 #ifndef gs_matrix_DEFINED 42 # define gs_matrix_DEFINED 43 typedef struct gs_matrix_s gs_matrix; 44 #endif 45 46 #ifndef ttfFont_DEFINED 47 # define ttfFont_DEFINED 48 typedef struct ttfFont_s ttfFont; 49 #endif 50 #ifndef gx_ttfReader_DEFINED 51 # define gx_ttfReader_DEFINED 52 typedef struct gx_ttfReader_s gx_ttfReader; 53 #endif 54 #ifndef ttfInterpreter_DEFINED 55 # define ttfInterpreter_DEFINED 56 typedef struct ttfInterpreter_s ttfInterpreter; 57 #endif 58 #ifndef gx_device_spot_analyzer_DEFINED 59 # define gx_device_spot_analyzer_DEFINED 60 typedef struct gx_device_spot_analyzer_s gx_device_spot_analyzer; 61 #endif 62 #ifndef gs_state_DEFINED 63 # define gs_state_DEFINED 64 typedef struct gs_state_s gs_state; 65 #endif 66 67 68 /* 69 * Define the entry for a cached (font,matrix) pair. If the UID 70 * is valid, the font pointer may be 0, since we keep entries even for 71 * fonts unloaded by a restore if they have valid UIDs; in this case, 72 * we also need the FontType as part of the key. 73 * Note that because of the dependency on StrokeWidth, we can't cache 74 * fonts with non-zero PaintType. 75 * We can't use the address of the pair for the hash value, 76 * since the GC may move pairs in storage, so we create a hash 77 * when we allocate the pair initially. 78 */ 79 struct cached_fm_pair_s { 80 gs_font *font; /* base font */ 81 gs_uid UID; /* font UniqueID or XUID */ 82 font_type FontType; /* (part of key if UID is valid) */ 83 uint hash; /* hash for this pair */ 84 float mxx, mxy, myx, myy; /* transformation */ 85 int num_chars; /* # of cached chars with this */ 86 /* f/m pair */ 87 bool xfont_tried; /* true if we looked up an xfont */ 88 gx_xfont *xfont; /* the xfont (if any) */ 89 gs_memory_t *memory; /* the allocator for the xfont */ 90 uint index; /* index of this pair in mdata */ 91 ttfFont *ttf; /* True Type interpreter data. */ 92 gx_ttfReader *ttr; /* True Type interpreter data. */ 93 bool design_grid; /* A charpath font face. */ 94 }; 95 96 #define private_st_cached_fm_pair() /* in gxccman.c */\ 97 gs_private_st_ptrs5(st_cached_fm_pair, cached_fm_pair,\ 98 "cached_fm_pair", fm_pair_enum_ptrs, fm_pair_reloc_ptrs,\ 99 font, UID.xvalues, xfont, ttf, ttr) 100 #define private_st_cached_fm_pair_elt() /* in gxccman.c */\ 101 gs_private_st_element(st_cached_fm_pair_element, cached_fm_pair,\ 102 "cached_fm_pair[]", fm_pair_element_enum_ptrs, fm_pair_element_reloc_ptrs,\ 103 st_cached_fm_pair) 104 /* If font == 0 and UID is invalid, this is a free entry. */ 105 #define fm_pair_is_free(pair)\ 106 ((pair)->font == 0 && !uid_is_valid(&(pair)->UID)) 107 #define fm_pair_set_free(pair)\ 108 ((pair)->font = 0, uid_set_invalid(&(pair)->UID)) 109 #define fm_pair_init(pair)\ 110 (fm_pair_set_free(pair), (pair)->xfont_tried = false, (pair)->xfont = 0) 111 112 /* The font/matrix pair cache itself. */ 113 typedef struct fm_pair_cache_s { 114 uint msize, mmax; /* # of cached font/matrix pairs */ 115 cached_fm_pair *mdata; 116 uint mnext; /* rover for allocating font/matrix pairs */ 117 } fm_pair_cache; 118 119 /* ------ Character cache entry ------- */ 120 121 /* Define the allocation chunk type. */ 122 typedef gx_bits_cache_chunk char_cache_chunk; 123 124 /* 125 * This is a subclass of the entry in a general bitmap cache. 126 * The character cache contains both used and free blocks. 127 * All blocks have a common header; free blocks have ONLY the header. 128 */ 129 typedef gx_cached_bits_head cached_char_head; 130 131 #define cc_head_is_free(cch) cb_head_is_free(cch) 132 #define cc_head_set_free(cch) cb_head_set_free(cch) 133 /* 134 * Define the cache entry for an individual character. 135 * The bits, if any, immediately follow the structure; 136 * characters with only xfont definitions may not have bits. 137 * An entry is 'real' if it is not free and if pair != 0. 138 * We maintain the invariant that at least one of the following must be true 139 * for all real entries: 140 * - cc_has_bits(cc); 141 * - cc->xglyph != gx_no_xglyph && cc_pair(cc)->xfont != 0. 142 */ 143 #ifndef cached_char_DEFINED 144 # define cached_char_DEFINED 145 typedef struct cached_char_s cached_char; 146 147 #endif 148 struct cached_char_s { 149 150 /* The code, font/matrix pair, wmode, and depth */ 151 /* are the 'key' in the cache. */ 152 /* gx_cached_bits_common includes depth. */ 153 154 gx_cached_bits_common; /* (must be first) */ 155 #define cc_depth(cc) ((cc)->cb_depth) 156 #define cc_set_depth(cc, d) ((cc)->cb_depth = (d)) 157 cached_fm_pair *pair; 158 bool linked; 159 #define cc_pair(cc) ((cc)->pair) 160 #define cc_set_pair_only(cc, p) ((cc)->pair = (p)) 161 gs_glyph code; /* glyph code */ 162 byte wmode; /* writing mode (0 or 1) */ 163 164 /* The following are neither 'key' nor 'value'. */ 165 166 char_cache_chunk *chunk; /* chunk where this char */ 167 /* is allocated */ 168 uint loc; /* relative location in chunk */ 169 uint pair_index; /* index of pair in mdata */ 170 gs_fixed_point subpix_origin; /* glyph origin offset modulo pixel */ 171 172 /* The rest of the structure is the 'value'. */ 173 /* gx_cached_bits_common has width, height, raster, */ 174 /* shift (not used here), id. */ 175 176 #define cc_raster(cc) ((cc)->raster) 177 #define cc_set_raster(cc, r) ((cc)->raster = (r)) 178 gx_xglyph xglyph; /* the xglyph for the xfont, if any */ 179 gs_fixed_point wxy; /* width in device coords */ 180 gs_fixed_point offset; /* (-llx, -lly) in device coords */ 181 }; 182 183 #define cc_is_free(cc) cc_head_is_free(&(cc)->head) 184 #define cc_set_free(cc) cc_head_set_free(&(cc)->head) 185 #define cc_set_pair(cc, p)\ 186 ((cc)->pair_index = ((cc)->pair = (p))->index) 187 #define cc_has_bits(cc) ((cc)->id != gx_no_bitmap_id) 188 /* 189 * Memory management for cached_chars is a little unusual. 190 * cached_chars are never instantiated on their own; a pointer to 191 * a cached_char points into the middle of a cache chunk. 192 * Consequently, such pointers can't be traced or relocated 193 * in the usual way. What we do instead is allocate the cache 194 * outside garbage-collectable space; we do all the tracing and relocating 195 * of pointers *from* the cache (currently only the head.pair pointer) 196 * when we trace or relocate the font "directory" that owns the cache. 197 * 198 * Since cached_chars are (currently) never instantiated on their own, 199 * they only have a descriptor so that cached_char_ptr can trace them. 200 */ 201 #define private_st_cached_char() /* in gxccman.c */\ 202 gs_private_st_composite(st_cached_char, cached_char, "cached_char",\ 203 cached_char_enum_ptrs, cached_char_reloc_ptrs) 204 #define private_st_cached_char_ptr() /* in gxccman.c */\ 205 gs_private_st_composite(st_cached_char_ptr, cached_char *,\ 206 "cached_char *", cc_ptr_enum_ptrs, cc_ptr_reloc_ptrs) 207 #define private_st_cached_char_ptr_elt() /* in gxccman.c */\ 208 gs_private_st_element(st_cached_char_ptr_element, cached_char *,\ 209 "cached_char *[]", cc_ptr_element_enum_ptrs, cc_ptr_element_reloc_ptrs,\ 210 st_cached_char_ptr) 211 212 /* 213 * Define the alignment and size of the cache structures. 214 */ 215 #define align_cached_char_mod align_cached_bits_mod 216 #define sizeof_cached_char\ 217 ROUND_UP(sizeof(cached_char), align_cached_char_mod) 218 #define cc_bits(cc) ((byte *)(cc) + sizeof_cached_char) 219 #define cc_const_bits(cc) ((const byte *)(cc) + sizeof_cached_char) 220 221 /* Define the hash index for a (glyph, fm_pair) key. */ 222 #define chars_head_index(glyph, pair)\ 223 ((uint)(glyph) * 59 + (pair)->hash * 73) /* scramble it a bit */ 224 225 /* ------ Character cache ------ */ 226 227 /* 228 * So that we can find all the entries in the cache without 229 * following chains of pointers, we use open hashing rather than 230 * chained hashing for the lookup table. 231 */ 232 typedef struct char_cache_s { 233 /* gx_bits_cache_common provides chunks, cnext, */ 234 /* bsize, csize. */ 235 gx_bits_cache_common; 236 gs_memory_t *struct_memory; 237 gs_memory_t *bits_memory; 238 cached_char **table; /* hash table */ 239 uint table_mask; /* (a power of 2 -1) */ 240 uint bmax; /* max bsize */ 241 uint cmax; /* max csize */ 242 uint bspace; /* space allocated for chunks */ 243 uint lower; /* min size at which cached chars */ 244 /* should be stored compressed */ 245 uint upper; /* max size of a single cached char */ 246 gs_glyph_mark_proc_t mark_glyph; 247 void *mark_glyph_data; /* closure data */ 248 } char_cache; 249 250 /* ------ Font/character cache ------ */ 251 252 /* A font "directory" (font/character cache manager). */ 253 #ifndef gs_font_dir_DEFINED 254 # define gs_font_dir_DEFINED 255 typedef struct gs_font_dir_s gs_font_dir; 256 #endif 257 struct gs_font_dir_s { 258 259 /* Original (unscaled) fonts */ 260 261 gs_font *orig_fonts; 262 263 /* Scaled font cache */ 264 265 gs_font *scaled_fonts; /* list of recently scaled fonts */ 266 uint ssize, smax; 267 268 /* Font/matrix pair cache */ 269 270 fm_pair_cache fmcache; 271 272 /* Character cache */ 273 274 char_cache ccache; 275 /* Scanning cache for GC */ 276 uint enum_index; /* index (N) */ 277 uint enum_offset; /* ccache.table[offset] is N'th non-zero entry */ 278 279 /* User parameter AlignToPixels. */ 280 bool align_to_pixels; 281 282 /* A table for converting glyphs to Unicode */ 283 void *glyph_to_unicode_table; /* closure data */ 284 285 /* An allocator for extension structures */ 286 gs_memory_t *memory; 287 ttfInterpreter *tti; 288 /* User parameter GridFitTT. */ 289 uint grid_fit_tt; 290 gx_device_spot_analyzer *san; 291 int (*global_glyph_code)(const gs_memory_t *mem, gs_const_string *gstr, gs_glyph *pglyph); 292 }; 293 294 #define private_st_font_dir() /* in gsfont.c */\ 295 gs_private_st_composite(st_font_dir, gs_font_dir, "gs_font_dir",\ 296 font_dir_enum_ptrs, font_dir_reloc_ptrs) 297 298 /* Enumerate the pointers in a font directory, except for orig_fonts. */ 299 #define font_dir_do_ptrs(m)\ 300 /*m(-,orig_fonts)*/ m(0,scaled_fonts) m(1,fmcache.mdata)\ 301 m(2,ccache.table) m(3,ccache.mark_glyph_data)\ 302 m(4,glyph_to_unicode_table) m(5,tti) m(6,san) 303 #define st_font_dir_max_ptrs 7 304 305 /* Character cache procedures (in gxccache.c and gxccman.c) */ 306 int gx_char_cache_alloc(gs_memory_t * struct_mem, gs_memory_t * bits_mem, 307 gs_font_dir * pdir, uint bmax, uint mmax, 308 uint cmax, uint upper); 309 void gx_char_cache_init(gs_font_dir *); 310 void gx_purge_selected_cached_chars(gs_font_dir *, 311 bool(*)(const gs_memory_t *, cached_char *, void *), void *); 312 void gx_compute_char_matrix(const gs_matrix *char_tm, const gs_log2_scale_point *log2_scale, 313 float *mxx, float *mxy, float *myx, float *myy); 314 void gx_compute_ccache_key(gs_font * pfont, const gs_matrix *char_tm, 315 const gs_log2_scale_point *log2_scale, bool design_grid, 316 float *mxx, float *mxy, float *myx, float *myy); 317 int gx_lookup_fm_pair(gs_font * pfont, const gs_matrix *char_tm, 318 const gs_log2_scale_point *log2_scale, bool design_grid, cached_fm_pair **ppair); 319 int gx_add_fm_pair(register gs_font_dir * dir, gs_font * font, const gs_uid * puid, 320 const gs_matrix * char_tm, const gs_log2_scale_point *log2_scale, 321 bool design_grid, cached_fm_pair **ppair); 322 void gx_lookup_xfont(const gs_state *, cached_fm_pair *, int); 323 void gs_purge_fm_pair(gs_font_dir *, cached_fm_pair *, int); 324 void gs_purge_font_from_char_caches(gs_font_dir *, const gs_font *); 325 326 #endif /* gxfcache_INCLUDED */ 327