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