1 /* Copyright (C) 1992, 1995, 1997, 1999 artofcode LLC. All rights reserved. 2 3 This program is free software; you can redistribute it and/or modify it 4 under the terms of the GNU General Public License as published by the 5 Free Software Foundation; either version 2 of the License, or (at your 6 option) any later version. 7 8 This program is distributed in the hope that it will be useful, but 9 WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along 14 with this program; if not, write to the Free Software Foundation, Inc., 15 59 Temple Place, Suite 330, Boston, MA, 02111-1307. 16 17 */ 18 19 /*$Id: gxfcache.h,v 1.2.6.1.2.1 2003/01/17 00:49:03 giles Exp $ */ 20 /* Font and character cache definitions and procedures */ 21 /* Requires gsfont.h */ 22 23 #ifndef gxfcache_INCLUDED 24 # define gxfcache_INCLUDED 25 26 #include "gsuid.h" 27 #include "gsxfont.h" 28 #include "gxbcache.h" 29 #include "gxftype.h" 30 31 /* ------ Font/matrix pair cache entry ------ */ 32 33 #ifndef cached_fm_pair_DEFINED 34 # define cached_fm_pair_DEFINED 35 typedef struct cached_fm_pair_s cached_fm_pair; 36 37 #endif 38 39 /* 40 * Define the entry for a cached (font,matrix) pair. If the UID 41 * is valid, the font pointer may be 0, since we keep entries even for 42 * fonts unloaded by a restore if they have valid UIDs; in this case, 43 * we also need the FontType as part of the key. 44 * Note that because of the dependency on StrokeWidth, we can't cache 45 * fonts with non-zero PaintType. 46 * We can't use the address of the pair for the hash value, 47 * since the GC may move pairs in storage, so we create a hash 48 * when we allocate the pair initially. 49 */ 50 struct cached_fm_pair_s { 51 gs_font *font; /* base font */ 52 gs_uid UID; /* font UniqueID or XUID */ 53 font_type FontType; /* (part of key if UID is valid) */ 54 uint hash; /* hash for this pair */ 55 float mxx, mxy, myx, myy; /* transformation */ 56 int num_chars; /* # of cached chars with this */ 57 /* f/m pair */ 58 bool xfont_tried; /* true if we looked up an xfont */ 59 gx_xfont *xfont; /* the xfont (if any) */ 60 gs_memory_t *memory; /* the allocator for the xfont */ 61 uint index; /* index of this pair in mdata */ 62 }; 63 64 #define private_st_cached_fm_pair() /* in gxccman.c */\ 65 gs_private_st_ptrs3(st_cached_fm_pair, cached_fm_pair,\ 66 "cached_fm_pair", fm_pair_enum_ptrs, fm_pair_reloc_ptrs,\ 67 font, UID.xvalues, xfont) 68 #define private_st_cached_fm_pair_elt() /* in gxccman.c */\ 69 gs_private_st_element(st_cached_fm_pair_element, cached_fm_pair,\ 70 "cached_fm_pair[]", fm_pair_element_enum_ptrs, fm_pair_element_reloc_ptrs,\ 71 st_cached_fm_pair) 72 /* If font == 0 and UID is invalid, this is a free entry. */ 73 #define fm_pair_is_free(pair)\ 74 ((pair)->font == 0 && !uid_is_valid(&(pair)->UID)) 75 #define fm_pair_set_free(pair)\ 76 ((pair)->font = 0, uid_set_invalid(&(pair)->UID)) 77 #define fm_pair_init(pair)\ 78 (fm_pair_set_free(pair), (pair)->xfont_tried = false, (pair)->xfont = 0) 79 80 /* The font/matrix pair cache itself. */ 81 typedef struct fm_pair_cache_s { 82 uint msize, mmax; /* # of cached font/matrix pairs */ 83 cached_fm_pair *mdata; 84 uint mnext; /* rover for allocating font/matrix pairs */ 85 } fm_pair_cache; 86 87 /* ------ Character cache entry ------- */ 88 89 /* Define the allocation chunk type. */ 90 typedef gx_bits_cache_chunk char_cache_chunk; 91 92 /* 93 * This is a subclass of the entry in a general bitmap cache. 94 * The character cache contains both used and free blocks. 95 * All blocks have a common header; free blocks have ONLY the header. 96 */ 97 typedef gx_cached_bits_head cached_char_head; 98 99 #define cc_head_is_free(cch) cb_head_is_free(cch) 100 #define cc_head_set_free(cch) cb_head_set_free(cch) 101 /* 102 * Define the cache entry for an individual character. 103 * The bits, if any, immediately follow the structure; 104 * characters with only xfont definitions may not have bits. 105 * An entry is 'real' if it is not free and if pair != 0. 106 * We maintain the invariant that at least one of the following must be true 107 * for all real entries: 108 * - cc_has_bits(cc); 109 * - cc->xglyph != gx_no_xglyph && cc_pair(cc)->xfont != 0. 110 */ 111 #ifndef cached_char_DEFINED 112 # define cached_char_DEFINED 113 typedef struct cached_char_s cached_char; 114 115 #endif 116 struct cached_char_s { 117 118 /* The code, font/matrix pair, wmode, and depth */ 119 /* are the 'key' in the cache. */ 120 /* gx_cached_bits_common includes depth. */ 121 122 gx_cached_bits_common; /* (must be first) */ 123 #define cc_depth(cc) ((cc)->cb_depth) 124 #define cc_set_depth(cc, d) ((cc)->cb_depth = (d)) 125 cached_fm_pair *pair; 126 #define cc_pair(cc) ((cc)->pair) 127 #define cc_set_pair_only(cc, p) ((cc)->pair = (p)) 128 gs_glyph code; /* glyph code */ 129 byte wmode; /* writing mode (0 or 1) */ 130 131 /* The following are neither 'key' nor 'value'. */ 132 133 char_cache_chunk *chunk; /* chunk where this char */ 134 /* is allocated */ 135 uint loc; /* relative location in chunk */ 136 uint pair_index; /* index of pair in mdata */ 137 138 /* The rest of the structure is the 'value'. */ 139 /* gx_cached_bits_common has width, height, raster, */ 140 /* shift (not used here), id. */ 141 142 #define cc_raster(cc) ((cc)->raster) 143 #define cc_set_raster(cc, r) ((cc)->raster = (r)) 144 gx_xglyph xglyph; /* the xglyph for the xfont, if any */ 145 gs_fixed_point wxy; /* width in device coords */ 146 gs_fixed_point offset; /* (-llx, -lly) in device coords */ 147 }; 148 149 #define cc_is_free(cc) cc_head_is_free(&(cc)->head) 150 #define cc_set_free(cc) cc_head_set_free(&(cc)->head) 151 #define cc_set_pair(cc, p)\ 152 ((cc)->pair_index = ((cc)->pair = (p))->index) 153 #define cc_has_bits(cc) ((cc)->id != gx_no_bitmap_id) 154 /* 155 * Memory management for cached_chars is a little unusual. 156 * cached_chars are never instantiated on their own; a pointer to 157 * a cached_char points into the middle of a cache chunk. 158 * Consequently, such pointers can't be traced or relocated 159 * in the usual way. What we do instead is allocate the cache 160 * outside garbage-collectable space; we do all the tracing and relocating 161 * of pointers *from* the cache (currently only the head.pair pointer) 162 * when we trace or relocate the font "directory" that owns the cache. 163 * 164 * Since cached_chars are (currently) never instantiated on their own, 165 * they only have a descriptor so that cached_char_ptr can trace them. 166 */ 167 #define private_st_cached_char() /* in gxccman.c */\ 168 gs_private_st_composite(st_cached_char, cached_char, "cached_char",\ 169 cached_char_enum_ptrs, cached_char_reloc_ptrs) 170 #define private_st_cached_char_ptr() /* in gxccman.c */\ 171 gs_private_st_composite(st_cached_char_ptr, cached_char *,\ 172 "cached_char *", cc_ptr_enum_ptrs, cc_ptr_reloc_ptrs) 173 #define private_st_cached_char_ptr_elt() /* in gxccman.c */\ 174 gs_private_st_element(st_cached_char_ptr_element, cached_char *,\ 175 "cached_char *[]", cc_ptr_element_enum_ptrs, cc_ptr_element_reloc_ptrs,\ 176 st_cached_char_ptr) 177 178 /* 179 * Define the alignment and size of the cache structures. 180 */ 181 #define align_cached_char_mod align_cached_bits_mod 182 #define sizeof_cached_char\ 183 ROUND_UP(sizeof(cached_char), align_cached_char_mod) 184 #define cc_bits(cc) ((byte *)(cc) + sizeof_cached_char) 185 #define cc_const_bits(cc) ((const byte *)(cc) + sizeof_cached_char) 186 187 /* Define the hash index for a (glyph, fm_pair) key. */ 188 #define chars_head_index(glyph, pair)\ 189 ((uint)(glyph) * 59 + (pair)->hash * 73) /* scramble it a bit */ 190 191 /* ------ Character cache ------ */ 192 193 /* 194 * So that we can find all the entries in the cache without 195 * following chains of pointers, we use open hashing rather than 196 * chained hashing for the lookup table. 197 */ 198 typedef struct char_cache_s { 199 /* gx_bits_cache_common provides chunks, cnext, */ 200 /* bsize, csize. */ 201 gx_bits_cache_common; 202 gs_memory_t *struct_memory; 203 gs_memory_t *bits_memory; 204 cached_char **table; /* hash table */ 205 uint table_mask; /* (a power of 2 -1) */ 206 uint bmax; /* max bsize */ 207 uint cmax; /* max csize */ 208 uint bspace; /* space allocated for chunks */ 209 uint lower; /* min size at which cached chars */ 210 /* should be stored compressed */ 211 uint upper; /* max size of a single cached char */ 212 gs_glyph_mark_proc_t mark_glyph; 213 void *mark_glyph_data; /* closure data */ 214 } char_cache; 215 216 /* ------ Font/character cache ------ */ 217 218 /* A font "directory" (font/character cache manager). */ 219 #ifndef gs_font_dir_DEFINED 220 # define gs_font_dir_DEFINED 221 typedef struct gs_font_dir_s gs_font_dir; 222 #endif 223 struct gs_font_dir_s { 224 225 /* Original (unscaled) fonts */ 226 227 gs_font *orig_fonts; 228 229 /* Scaled font cache */ 230 231 gs_font *scaled_fonts; /* list of recently scaled fonts */ 232 uint ssize, smax; 233 234 /* Font/matrix pair cache */ 235 236 fm_pair_cache fmcache; 237 238 /* Character cache */ 239 240 char_cache ccache; 241 /* Scanning cache for GC */ 242 uint enum_index; /* index (N) */ 243 uint enum_offset; /* ccache.table[offset] is N'th non-zero entry */ 244 }; 245 246 #define private_st_font_dir() /* in gsfont.c */\ 247 gs_private_st_composite(st_font_dir, gs_font_dir, "gs_font_dir",\ 248 font_dir_enum_ptrs, font_dir_reloc_ptrs) 249 250 /* Enumerate the pointers in a font directory, except for orig_fonts. */ 251 #define font_dir_do_ptrs(m)\ 252 /*m(-,orig_fonts)*/ m(0,scaled_fonts) m(1,fmcache.mdata)\ 253 m(2,ccache.table) m(3,ccache.mark_glyph_data) 254 #define st_font_dir_max_ptrs 4 255 256 /* Character cache procedures (in gxccache.c and gxccman.c) */ 257 int gx_char_cache_alloc(P7(gs_memory_t * struct_mem, gs_memory_t * bits_mem, 258 gs_font_dir * pdir, uint bmax, uint mmax, 259 uint cmax, uint upper)); 260 void gx_char_cache_init(P1(gs_font_dir *)); 261 void gx_purge_selected_cached_chars(P3(gs_font_dir *, bool(*)(P2(cached_char *, void *)), void *)); 262 cached_fm_pair * 263 gx_lookup_fm_pair(P2(gs_font *, const gs_state *)); 264 cached_fm_pair * 265 gx_add_fm_pair(P4(gs_font_dir *, gs_font *, const gs_uid *, const gs_state *)); 266 void gx_lookup_xfont(P3(const gs_state *, cached_fm_pair *, int)); 267 void gs_purge_fm_pair(P3(gs_font_dir *, cached_fm_pair *, int)); 268 269 #endif /* gxfcache_INCLUDED */ 270