sdk-world
v2026.11.05
PS2 SDK - world tier (copyleft-allowed, non-essential packages)
Toggle main menu visibility
Loading...
Searching...
No Matches
ftccache.h
Go to the documentation of this file.
1
/****************************************************************************
2
*
3
* ftccache.h
4
*
5
* FreeType internal cache interface (specification).
6
*
7
* Copyright (C) 2000-2025 by
8
* David Turner, Robert Wilhelm, and Werner Lemberg.
9
*
10
* This file is part of the FreeType project, and may only be used,
11
* modified, and distributed under the terms of the FreeType project
12
* license, LICENSE.TXT. By continuing to use, modify, or distribute
13
* this file you indicate that you have read the license and
14
* understand and accept it fully.
15
*
16
*/
17
18
23
#ifndef FTCCACHE_H_
24
#define FTCCACHE_H_
25
26
#include <
freetype/internal/compiler-macros.h
>
27
#include "
ftcmru.h
"
28
29
FT_BEGIN_HEADER
30
31
#define FTC_FACE_ID_HASH( i ) \
32
( ( (FT_Offset)(i) >> 3 ) ^ ( (FT_Offset)(i) << 7 ) )
33
34
/* handle to cache object */
35
typedef
struct
FTC_CacheRec_
* FTC_Cache;
36
37
/* handle to cache class */
38
typedef
const
struct
FTC_CacheClassRec_
* FTC_CacheClass;
39
40
41
/*************************************************************************/
42
/*************************************************************************/
43
/***** *****/
44
/***** CACHE NODE DEFINITIONS *****/
45
/***** *****/
46
/*************************************************************************/
47
/*************************************************************************/
48
49
/**************************************************************************
50
*
51
* Each cache controls one or more cache nodes. Each node is part of
52
* the global_lru list of the manager. Its `data' field however is used
53
* as a reference count for now.
54
*
55
* A node can be anything, depending on the type of information held by
56
* the cache. It can be an individual glyph image, a set of bitmaps
57
* glyphs for a given size, some metrics, etc.
58
*
59
*/
60
61
/* structure size should be 20 bytes on 32-bits machines */
62
typedef
struct
FTC_NodeRec_
63
{
64
FTC_MruNodeRec mru;
/* circular mru list pointer */
65
FTC_Node link;
/* used for hashing */
66
FT_Offset hash;
/* used for hashing too */
67
FT_UShort cache_index;
/* index of cache the node belongs to */
68
FT_Short ref_count;
/* reference count for this node */
69
70
} FTC_NodeRec;
71
72
73
#define FTC_NODE( x ) ( (FTC_Node)(x) )
74
#define FTC_NODE_P( x ) ( (FTC_Node*)(x) )
75
76
#define FTC_NODE_NEXT( x ) FTC_NODE( (x)->mru.next )
77
#define FTC_NODE_PREV( x ) FTC_NODE( (x)->mru.prev )
78
79
/* address the hash table entries */
80
#ifdef FTC_INLINE
81
#define FTC_NODE_TOP_FOR_HASH( cache, hash ) \
82
( ( cache )->buckets + \
83
( ( ( ( hash ) & ( cache )->mask ) >= ( cache )->p ) \
84
? ( ( hash ) & ( ( cache )->mask >> 1 ) ) \
85
: ( ( hash ) & ( cache )->mask ) ) )
86
#else
87
FT_LOCAL( FTC_Node* )
88
ftc_get_top_node_for_hash( FTC_Cache cache,
89
FT_Offset hash );
90
#define FTC_NODE_TOP_FOR_HASH( cache, hash ) \
91
ftc_get_top_node_for_hash( ( cache ), ( hash ) )
92
#endif
93
94
FT_LOCAL(
void
)
95
ftc_node_destroy( FTC_Node node,
96
FTC_Manager manager );
97
98
99
/*************************************************************************/
100
/*************************************************************************/
101
/***** *****/
102
/***** CACHE DEFINITIONS *****/
103
/***** *****/
104
/*************************************************************************/
105
/*************************************************************************/
106
107
/* initialize a new cache node */
108
typedef
FT_Error
109
(*FTC_Node_NewFunc)( FTC_Node *pnode,
110
FT_Pointer query,
111
FTC_Cache cache );
112
113
typedef
FT_Offset
114
(*FTC_Node_WeightFunc)( FTC_Node node,
115
FTC_Cache cache );
116
117
/* compare a node to a given key pair */
118
typedef
FT_Bool
119
(*FTC_Node_CompareFunc)( FTC_Node node,
120
FT_Pointer key,
121
FTC_Cache cache,
122
FT_Bool* list_changed );
123
124
125
typedef
void
126
(*FTC_Node_FreeFunc)( FTC_Node node,
127
FTC_Cache cache );
128
129
typedef
FT_Error
130
(*FTC_Cache_InitFunc)( FTC_Cache cache );
131
132
typedef
void
133
(*FTC_Cache_DoneFunc)( FTC_Cache cache );
134
135
136
typedef
struct
FTC_CacheClassRec_
137
{
138
FTC_Node_NewFunc node_new;
139
FTC_Node_WeightFunc node_weight;
140
FTC_Node_CompareFunc node_compare;
141
FTC_Node_CompareFunc node_remove_faceid;
142
FTC_Node_FreeFunc node_free;
143
144
FT_Offset cache_size;
145
FTC_Cache_InitFunc cache_init;
146
FTC_Cache_DoneFunc cache_done;
147
148
} FTC_CacheClassRec;
149
150
151
/* each cache really implements a hash table to manage its nodes */
152
/* the number of the table entries (buckets) can change dynamically */
153
/* each bucket contains a linked lists of nodes for a given hash */
154
typedef
struct
FTC_CacheRec_
155
{
156
FT_UFast p;
/* hash table counter */
157
FT_UFast mask;
/* hash table index range */
158
FT_Long slack;
159
FTC_Node* buckets;
160
161
FTC_CacheClassRec clazz;
/* local copy, for speed */
162
163
FTC_Manager manager;
164
FT_Memory memory;
165
FT_UInt index;
/* in manager's table */
166
167
FTC_CacheClass org_class;
/* original class pointer */
168
169
} FTC_CacheRec;
170
171
172
#define FTC_CACHE( x ) ( (FTC_Cache)(x) )
173
#define FTC_CACHE_P( x ) ( (FTC_Cache*)(x) )
174
175
176
/* default cache initialize */
177
FT_LOCAL( FT_Error )
178
FTC_Cache_Init( FTC_Cache cache );
179
180
/* default cache finalizer */
181
FT_LOCAL(
void
)
182
FTC_Cache_Done( FTC_Cache cache );
183
184
/* Call this function to look up the cache. If no corresponding
185
* node is found, a new one is automatically created. This function
186
* is capable of flushing the cache adequately to make room for the
187
* new cache object.
188
*/
189
190
#ifndef FTC_INLINE
191
FT_LOCAL( FT_Error )
192
FTC_Cache_Lookup( FTC_Cache cache,
193
FT_Offset hash,
194
FT_Pointer query,
195
FTC_Node *anode );
196
#endif
197
198
FT_LOCAL( FT_Error )
199
FTC_Cache_NewNode( FTC_Cache cache,
200
FT_Offset hash,
201
FT_Pointer query,
202
FTC_Node *anode );
203
204
/* Remove all nodes that relate to a given face_id. This is useful
205
* when un-installing fonts. Note that if a cache node relates to
206
* the face_id but is locked (i.e., has `ref_count > 0'), the node
207
* will _not_ be destroyed, but its internal face_id reference will
208
* be modified.
209
*
210
* The final result will be that the node will never come back
211
* in further lookup requests, and will be flushed on demand from
212
* the cache normally when its reference count reaches 0.
213
*/
214
FT_LOCAL(
void
)
215
FTC_Cache_RemoveFaceID( FTC_Cache cache,
216
FTC_FaceID face_id );
217
218
219
#ifdef FTC_INLINE
220
221
#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \
222
FT_BEGIN_STMNT \
223
FTC_Node *_bucket, *_pnode, _node; \
224
FTC_Cache _cache = FTC_CACHE( cache ); \
225
FT_Offset _hash = (FT_Offset)(hash); \
226
FTC_Node_CompareFunc _nodcomp = (FTC_Node_CompareFunc)(nodecmp); \
227
FT_Bool _list_changed = FALSE; \
228
\
229
\
230
error = FT_Err_Ok; \
231
node = NULL; \
232
\
233
/* Go to the `top' node of the list sharing same masked hash */
\
234
_bucket = _pnode = FTC_NODE_TOP_FOR_HASH( _cache, _hash ); \
235
\
236
/* Look up a node with identical hash and queried properties. */
\
237
/* NOTE: _nodcomp() may change the linked list to reduce memory. */
\
238
for (;;) \
239
{ \
240
_node = *_pnode; \
241
if ( !_node ) \
242
goto NewNode_; \
243
\
244
if ( _node->hash == _hash && \
245
_nodcomp( _node, query, _cache, &_list_changed ) ) \
246
break; \
247
\
248
_pnode = &_node->link; \
249
} \
250
\
251
if ( _list_changed ) \
252
{ \
253
/* Update _bucket by possibly modified linked list */
\
254
_bucket = _pnode = FTC_NODE_TOP_FOR_HASH( _cache, _hash ); \
255
\
256
/* Update _pnode by possibly modified linked list */
\
257
while ( *_pnode != _node ) \
258
{ \
259
if ( !*_pnode ) \
260
{ \
261
FT_ERROR(( "FTC_CACHE_LOOKUP_CMP: oops!!! node missing\n" )); \
262
goto NewNode_; \
263
} \
264
else \
265
_pnode = &(*_pnode)->link; \
266
} \
267
} \
268
\
269
/* Reorder the list to move the found node to the `top' */
\
270
if ( _node != *_bucket ) \
271
{ \
272
*_pnode = _node->link; \
273
_node->link = *_bucket; \
274
*_bucket = _node; \
275
} \
276
\
277
/* Update MRU list */
\
278
{ \
279
FTC_Manager _manager = _cache->manager; \
280
void* _nl = &_manager->nodes_list; \
281
\
282
\
283
if ( _node != _manager->nodes_list ) \
284
FTC_MruNode_Up( (FTC_MruNode*)_nl, \
285
(FTC_MruNode)_node ); \
286
} \
287
goto Ok_; \
288
\
289
NewNode_: \
290
error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \
291
\
292
Ok_: \
293
node = _node; \
294
FT_END_STMNT
295
296
#else
/* !FTC_INLINE */
297
298
#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ) \
299
FT_BEGIN_STMNT \
300
error = FTC_Cache_Lookup( FTC_CACHE( cache ), hash, query, \
301
(FTC_Node*)&(node) ); \
302
FT_END_STMNT
303
304
#endif
/* !FTC_INLINE */
305
306
307
/*
308
* This macro, together with FTC_CACHE_TRYLOOP_END, defines a retry
309
* loop to flush the cache repeatedly in case of memory overflows.
310
*
311
* It is used when creating a new cache node, or within a lookup
312
* that needs to allocate data (e.g. the sbit cache lookup).
313
*
314
* Example:
315
*
316
* {
317
* FTC_CACHE_TRYLOOP( cache )
318
* error = load_data( ... );
319
* FTC_CACHE_TRYLOOP_END()
320
* }
321
*
322
*/
323
#define FTC_CACHE_TRYLOOP( cache ) \
324
{ \
325
FTC_Manager _try_manager = FTC_CACHE( cache )->manager; \
326
FT_UInt _try_count = 4; \
327
\
328
\
329
for (;;) \
330
{ \
331
FT_UInt _try_done;
332
333
334
#define FTC_CACHE_TRYLOOP_END( list_changed ) \
335
if ( !error || FT_ERR_NEQ( error, Out_Of_Memory ) ) \
336
break; \
337
\
338
_try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \
339
if ( _try_done > 0 && list_changed != NULL ) \
340
*(FT_Bool*)( list_changed ) = TRUE; \
341
\
342
if ( _try_done == 0 ) \
343
break; \
344
\
345
if ( _try_done == _try_count ) \
346
{ \
347
_try_count *= 2; \
348
if ( _try_count < _try_done || \
349
_try_count > _try_manager->num_nodes ) \
350
_try_count = _try_manager->num_nodes; \
351
} \
352
} \
353
}
354
355
/* */
356
357
FT_END_HEADER
358
359
360
#endif
/* FTCCACHE_H_ */
361
362
363
/* END */
compiler-macros.h
ftcmru.h
FTC_CacheClassRec_
Definition
ftccache.h:137
FTC_CacheRec_
Definition
ftccache.h:155
FTC_NodeRec_
Definition
ftccache.h:63
freetype
src
cache
ftccache.h
Generated by
1.18.0