Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 1 | /***************************************************************************/ |
2 | /* */ |
||
3 | /* ftcmru.h */ |
||
4 | /* */ |
||
5 | /* Simple MRU list-cache (specification). */ |
||
6 | /* */ |
||
7 | /* Copyright 2000-2001, 2003-2006, 2010, 2013 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 | |||
19 | /*************************************************************************/ |
||
20 | /* */ |
||
21 | /* An MRU is a list that cannot hold more than a certain number of */ |
||
22 | /* elements (`max_elements'). All elements in the list are sorted in */ |
||
23 | /* least-recently-used order, i.e., the `oldest' element is at the tail */ |
||
24 | /* of the list. */ |
||
25 | /* */ |
||
26 | /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'), */ |
||
27 | /* the list is searched for an element with the corresponding key. If */ |
||
28 | /* it is found, the element is moved to the head of the list and is */ |
||
29 | /* returned. */ |
||
30 | /* */ |
||
31 | /* If no corresponding element is found, the lookup routine will try to */ |
||
32 | /* obtain a new element with the relevant key. If the list is already */ |
||
33 | /* full, the oldest element from the list is discarded and replaced by a */ |
||
34 | /* new one; a new element is added to the list otherwise. */ |
||
35 | /* */ |
||
36 | /* Note that it is possible to pre-allocate the element list nodes. */ |
||
37 | /* This is handy if `max_elements' is sufficiently small, as it saves */ |
||
38 | /* allocations/releases during the lookup process. */ |
||
39 | /* */ |
||
40 | /*************************************************************************/ |
||
41 | |||
42 | |||
43 | #ifndef __FTCMRU_H__ |
||
44 | #define __FTCMRU_H__ |
||
45 | |||
46 | |||
47 | #include |
||
48 | #include FT_FREETYPE_H |
||
49 | |||
50 | #ifdef FREETYPE_H |
||
51 | #error "freetype.h of FreeType 1 has been loaded!" |
||
52 | #error "Please fix the directory search order for header files" |
||
53 | #error "so that freetype.h of FreeType 2 is found first." |
||
54 | #endif |
||
55 | |||
56 | #define xxFT_DEBUG_ERROR |
||
57 | #define FTC_INLINE |
||
58 | |||
59 | FT_BEGIN_HEADER |
||
60 | |||
61 | typedef struct FTC_MruNodeRec_* FTC_MruNode; |
||
62 | |||
63 | typedef struct FTC_MruNodeRec_ |
||
64 | { |
||
65 | FTC_MruNode next; |
||
66 | FTC_MruNode prev; |
||
67 | |||
68 | } FTC_MruNodeRec; |
||
69 | |||
70 | |||
71 | FT_LOCAL( void ) |
||
72 | FTC_MruNode_Prepend( FTC_MruNode *plist, |
||
73 | FTC_MruNode node ); |
||
74 | |||
75 | FT_LOCAL( void ) |
||
76 | FTC_MruNode_Up( FTC_MruNode *plist, |
||
77 | FTC_MruNode node ); |
||
78 | |||
79 | FT_LOCAL( void ) |
||
80 | FTC_MruNode_Remove( FTC_MruNode *plist, |
||
81 | FTC_MruNode node ); |
||
82 | |||
83 | |||
84 | typedef struct FTC_MruListRec_* FTC_MruList; |
||
85 | |||
86 | typedef struct FTC_MruListClassRec_ const * FTC_MruListClass; |
||
87 | |||
88 | |||
89 | typedef FT_Bool |
||
90 | (*FTC_MruNode_CompareFunc)( FTC_MruNode node, |
||
91 | FT_Pointer key ); |
||
92 | |||
93 | typedef FT_Error |
||
94 | (*FTC_MruNode_InitFunc)( FTC_MruNode node, |
||
95 | FT_Pointer key, |
||
96 | FT_Pointer data ); |
||
97 | |||
98 | typedef FT_Error |
||
99 | (*FTC_MruNode_ResetFunc)( FTC_MruNode node, |
||
100 | FT_Pointer key, |
||
101 | FT_Pointer data ); |
||
102 | |||
103 | typedef void |
||
104 | (*FTC_MruNode_DoneFunc)( FTC_MruNode node, |
||
105 | FT_Pointer data ); |
||
106 | |||
107 | |||
108 | typedef struct FTC_MruListClassRec_ |
||
109 | { |
||
110 | FT_Offset node_size; |
||
111 | FTC_MruNode_CompareFunc node_compare; |
||
112 | FTC_MruNode_InitFunc node_init; |
||
113 | FTC_MruNode_ResetFunc node_reset; |
||
114 | FTC_MruNode_DoneFunc node_done; |
||
115 | |||
116 | } FTC_MruListClassRec; |
||
117 | |||
118 | typedef struct FTC_MruListRec_ |
||
119 | { |
||
120 | FT_UInt num_nodes; |
||
121 | FT_UInt max_nodes; |
||
122 | FTC_MruNode nodes; |
||
123 | FT_Pointer data; |
||
124 | FTC_MruListClassRec clazz; |
||
125 | FT_Memory memory; |
||
126 | |||
127 | } FTC_MruListRec; |
||
128 | |||
129 | |||
130 | FT_LOCAL( void ) |
||
131 | FTC_MruList_Init( FTC_MruList list, |
||
132 | FTC_MruListClass clazz, |
||
133 | FT_UInt max_nodes, |
||
134 | FT_Pointer data, |
||
135 | FT_Memory memory ); |
||
136 | |||
137 | FT_LOCAL( void ) |
||
138 | FTC_MruList_Reset( FTC_MruList list ); |
||
139 | |||
140 | |||
141 | FT_LOCAL( void ) |
||
142 | FTC_MruList_Done( FTC_MruList list ); |
||
143 | |||
144 | |||
145 | FT_LOCAL( FT_Error ) |
||
146 | FTC_MruList_New( FTC_MruList list, |
||
147 | FT_Pointer key, |
||
148 | FTC_MruNode *anode ); |
||
149 | |||
150 | FT_LOCAL( void ) |
||
151 | FTC_MruList_Remove( FTC_MruList list, |
||
152 | FTC_MruNode node ); |
||
153 | |||
154 | FT_LOCAL( void ) |
||
155 | FTC_MruList_RemoveSelection( FTC_MruList list, |
||
156 | FTC_MruNode_CompareFunc selection, |
||
157 | FT_Pointer key ); |
||
158 | |||
159 | |||
160 | #ifdef FTC_INLINE |
||
161 | |||
162 | #define FTC_MRULIST_LOOKUP_CMP( list, key, compare, node, error ) \ |
||
163 | FT_BEGIN_STMNT \ |
||
164 | FTC_MruNode* _pfirst = &(list)->nodes; \ |
||
165 | FTC_MruNode_CompareFunc _compare = (FTC_MruNode_CompareFunc)(compare); \ |
||
166 | FTC_MruNode _first, _node; \ |
||
167 | \ |
||
168 | \ |
||
169 | error = FT_Err_Ok; \ |
||
170 | _first = *(_pfirst); \ |
||
171 | _node = NULL; \ |
||
172 | \ |
||
173 | if ( _first ) \ |
||
174 | { \ |
||
175 | _node = _first; \ |
||
176 | do \ |
||
177 | { \ |
||
178 | if ( _compare( _node, (key) ) ) \ |
||
179 | { \ |
||
180 | if ( _node != _first ) \ |
||
181 | FTC_MruNode_Up( _pfirst, _node ); \ |
||
182 | \ |
||
183 | node = _node; \ |
||
184 | goto _MruOk; \ |
||
185 | } \ |
||
186 | _node = _node->next; \ |
||
187 | \ |
||
188 | } while ( _node != _first) ; \ |
||
189 | } \ |
||
190 | \ |
||
191 | error = FTC_MruList_New( (list), (key), (FTC_MruNode*)(void*)&(node) ); \ |
||
192 | _MruOk: \ |
||
193 | ; \ |
||
194 | FT_END_STMNT |
||
195 | |||
196 | #define FTC_MRULIST_LOOKUP( list, key, node, error ) \ |
||
197 | FTC_MRULIST_LOOKUP_CMP( list, key, (list)->clazz.node_compare, node, error ) |
||
198 | |||
199 | #else /* !FTC_INLINE */ |
||
200 | |||
201 | FT_LOCAL( FTC_MruNode ) |
||
202 | FTC_MruList_Find( FTC_MruList list, |
||
203 | FT_Pointer key ); |
||
204 | |||
205 | FT_LOCAL( FT_Error ) |
||
206 | FTC_MruList_Lookup( FTC_MruList list, |
||
207 | FT_Pointer key, |
||
208 | FTC_MruNode *pnode ); |
||
209 | |||
210 | #define FTC_MRULIST_LOOKUP( list, key, node, error ) \ |
||
211 | error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) ) |
||
212 | |||
213 | #endif /* !FTC_INLINE */ |
||
214 | |||
215 | |||
216 | #define FTC_MRULIST_LOOP( list, node ) \ |
||
217 | FT_BEGIN_STMNT \ |
||
218 | FTC_MruNode _first = (list)->nodes; \ |
||
219 | \ |
||
220 | \ |
||
221 | if ( _first ) \ |
||
222 | { \ |
||
223 | FTC_MruNode _node = _first; \ |
||
224 | \ |
||
225 | \ |
||
226 | do \ |
||
227 | { \ |
||
228 | *(FTC_MruNode*)&(node) = _node; |
||
229 | |||
230 | |||
231 | #define FTC_MRULIST_LOOP_END() \ |
||
232 | _node = _node->next; \ |
||
233 | \ |
||
234 | } while ( _node != _first ); \ |
||
235 | } \ |
||
236 | FT_END_STMNT |
||
237 | |||
238 | /* */ |
||
239 | |||
240 | FT_END_HEADER |
||
241 | |||
242 | |||
243 | #endif /* __FTCMRU_H__ */ |
||
244 | |||
245 | |||
246 | /* END */ |