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