2 |
- |
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 */
|