1 /***************************************************************************/ |
|
2 /* */ |
|
3 /* ftcglyph.h */ |
|
4 /* */ |
|
5 /* FreeType abstract glyph cache (specification). */ |
|
6 /* */ |
|
7 /* Copyright 2000-2001, 2003, 2004, 2006, 2007, 2011 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 * FTC_GCache is an _abstract_ cache object optimized to store glyph |
|
22 * data. It works as follows: |
|
23 * |
|
24 * - It manages FTC_GNode objects. Each one of them can hold one or more |
|
25 * glyph `items'. Item types are not specified in the FTC_GCache but |
|
26 * in classes that extend it. |
|
27 * |
|
28 * - Glyph attributes, like face ID, character size, render mode, etc., |
|
29 * can be grouped into abstract `glyph families'. This avoids storing |
|
30 * the attributes within the FTC_GCache, since it is likely that many |
|
31 * FTC_GNodes will belong to the same family in typical uses. |
|
32 * |
|
33 * - Each FTC_GNode is thus an FTC_Node with two additional fields: |
|
34 * |
|
35 * * gindex: A glyph index, or the first index in a glyph range. |
|
36 * * family: A pointer to a glyph `family'. |
|
37 * |
|
38 * - Family types are not fully specific in the FTC_Family type, but |
|
39 * by classes that extend it. |
|
40 * |
|
41 * Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache. |
|
42 * They share an FTC_Family sub-class called FTC_BasicFamily which is |
|
43 * used to store the following data: face ID, pixel/point sizes, load |
|
44 * flags. For more details see the file `src/cache/ftcbasic.c'. |
|
45 * |
|
46 * Client applications can extend FTC_GNode with their own FTC_GNode |
|
47 * and FTC_Family sub-classes to implement more complex caches (e.g., |
|
48 * handling automatic synthesis, like obliquing & emboldening, colored |
|
49 * glyphs, etc.). |
|
50 * |
|
51 * See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and |
|
52 * `ftcsbits.h', which both extend FTC_GCache with additional |
|
53 * optimizations. |
|
54 * |
|
55 * A typical FTC_GCache implementation must provide at least the |
|
56 * following: |
|
57 * |
|
58 * - FTC_GNode sub-class, e.g. MyNode, with relevant methods: |
|
59 * my_node_new (must call FTC_GNode_Init) |
|
60 * my_node_free (must call FTC_GNode_Done) |
|
61 * my_node_compare (must call FTC_GNode_Compare) |
|
62 * my_node_remove_faceid (must call ftc_gnode_unselect in case |
|
63 * of match) |
|
64 * |
|
65 * - FTC_Family sub-class, e.g. MyFamily, with relevant methods: |
|
66 * my_family_compare |
|
67 * my_family_init |
|
68 * my_family_reset (optional) |
|
69 * my_family_done |
|
70 * |
|
71 * - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query |
|
72 * data. |
|
73 * |
|
74 * - Constant structures for a FTC_GNodeClass. |
|
75 * |
|
76 * - MyCacheNew() can be implemented easily as a call to the convenience |
|
77 * function FTC_GCache_New. |
|
78 * |
|
79 * - MyCacheLookup with a call to FTC_GCache_Lookup. This function will |
|
80 * automatically: |
|
81 * |
|
82 * - Search for the corresponding family in the cache, or create |
|
83 * a new one if necessary. Put it in FTC_GQUERY(myquery).family |
|
84 * |
|
85 * - Call FTC_Cache_Lookup. |
|
86 * |
|
87 * If it returns NULL, you should create a new node, then call |
|
88 * ftc_cache_add as usual. |
|
89 */ |
|
90 |
|
91 |
|
92 /*************************************************************************/ |
|
93 /* */ |
|
94 /* Important: The functions defined in this file are only used to */ |
|
95 /* implement an abstract glyph cache class. You need to */ |
|
96 /* provide additional logic to implement a complete cache. */ |
|
97 /* */ |
|
98 /*************************************************************************/ |
|
99 |
|
100 |
|
101 /*************************************************************************/ |
|
102 /*************************************************************************/ |
|
103 /*************************************************************************/ |
|
104 /*************************************************************************/ |
|
105 /*************************************************************************/ |
|
106 /********* *********/ |
|
107 /********* WARNING, THIS IS BETA CODE. *********/ |
|
108 /********* *********/ |
|
109 /*************************************************************************/ |
|
110 /*************************************************************************/ |
|
111 /*************************************************************************/ |
|
112 /*************************************************************************/ |
|
113 /*************************************************************************/ |
|
114 |
|
115 |
|
116 #ifndef __FTCGLYPH_H__ |
|
117 #define __FTCGLYPH_H__ |
|
118 |
|
119 |
|
120 #include <ft2build.h> |
|
121 #include "ftcmanag.h" |
|
122 |
|
123 |
|
124 FT_BEGIN_HEADER |
|
125 |
|
126 |
|
127 /* |
|
128 * We can group glyphs into `families'. Each family correspond to a |
|
129 * given face ID, character size, transform, etc. |
|
130 * |
|
131 * Families are implemented as MRU list nodes. They are |
|
132 * reference-counted. |
|
133 */ |
|
134 |
|
135 typedef struct FTC_FamilyRec_ |
|
136 { |
|
137 FTC_MruNodeRec mrunode; |
|
138 FT_UInt num_nodes; /* current number of nodes in this family */ |
|
139 FTC_Cache cache; |
|
140 FTC_MruListClass clazz; |
|
141 |
|
142 } FTC_FamilyRec, *FTC_Family; |
|
143 |
|
144 #define FTC_FAMILY(x) ( (FTC_Family)(x) ) |
|
145 #define FTC_FAMILY_P(x) ( (FTC_Family*)(x) ) |
|
146 |
|
147 |
|
148 typedef struct FTC_GNodeRec_ |
|
149 { |
|
150 FTC_NodeRec node; |
|
151 FTC_Family family; |
|
152 FT_UInt gindex; |
|
153 |
|
154 } FTC_GNodeRec, *FTC_GNode; |
|
155 |
|
156 #define FTC_GNODE( x ) ( (FTC_GNode)(x) ) |
|
157 #define FTC_GNODE_P( x ) ( (FTC_GNode*)(x) ) |
|
158 |
|
159 |
|
160 typedef struct FTC_GQueryRec_ |
|
161 { |
|
162 FT_UInt gindex; |
|
163 FTC_Family family; |
|
164 |
|
165 } FTC_GQueryRec, *FTC_GQuery; |
|
166 |
|
167 #define FTC_GQUERY( x ) ( (FTC_GQuery)(x) ) |
|
168 |
|
169 |
|
170 /*************************************************************************/ |
|
171 /* */ |
|
172 /* These functions are exported so that they can be called from */ |
|
173 /* user-provided cache classes; otherwise, they are really part of the */ |
|
174 /* cache sub-system internals. */ |
|
175 /* */ |
|
176 |
|
177 /* must be called by derived FTC_Node_InitFunc routines */ |
|
178 FT_LOCAL( void ) |
|
179 FTC_GNode_Init( FTC_GNode node, |
|
180 FT_UInt gindex, /* glyph index for node */ |
|
181 FTC_Family family ); |
|
182 |
|
183 #ifdef FTC_INLINE |
|
184 |
|
185 /* returns TRUE iff the query's glyph index correspond to the node; */ |
|
186 /* this assumes that the `family' and `hash' fields of the query are */ |
|
187 /* already correctly set */ |
|
188 FT_LOCAL( FT_Bool ) |
|
189 FTC_GNode_Compare( FTC_GNode gnode, |
|
190 FTC_GQuery gquery, |
|
191 FTC_Cache cache, |
|
192 FT_Bool* list_changed ); |
|
193 |
|
194 #endif |
|
195 |
|
196 /* call this function to clear a node's family -- this is necessary */ |
|
197 /* to implement the `node_remove_faceid' cache method correctly */ |
|
198 FT_LOCAL( void ) |
|
199 FTC_GNode_UnselectFamily( FTC_GNode gnode, |
|
200 FTC_Cache cache ); |
|
201 |
|
202 /* must be called by derived FTC_Node_DoneFunc routines */ |
|
203 FT_LOCAL( void ) |
|
204 FTC_GNode_Done( FTC_GNode node, |
|
205 FTC_Cache cache ); |
|
206 |
|
207 |
|
208 FT_LOCAL( void ) |
|
209 FTC_Family_Init( FTC_Family family, |
|
210 FTC_Cache cache ); |
|
211 |
|
212 typedef struct FTC_GCacheRec_ |
|
213 { |
|
214 FTC_CacheRec cache; |
|
215 FTC_MruListRec families; |
|
216 |
|
217 } FTC_GCacheRec, *FTC_GCache; |
|
218 |
|
219 #define FTC_GCACHE( x ) ((FTC_GCache)(x)) |
|
220 |
|
221 |
|
222 #if 0 |
|
223 /* can be used as @FTC_Cache_InitFunc */ |
|
224 FT_LOCAL( FT_Error ) |
|
225 FTC_GCache_Init( FTC_GCache cache ); |
|
226 #endif |
|
227 |
|
228 |
|
229 #if 0 |
|
230 /* can be used as @FTC_Cache_DoneFunc */ |
|
231 FT_LOCAL( void ) |
|
232 FTC_GCache_Done( FTC_GCache cache ); |
|
233 #endif |
|
234 |
|
235 |
|
236 /* the glyph cache class adds fields for the family implementation */ |
|
237 typedef struct FTC_GCacheClassRec_ |
|
238 { |
|
239 FTC_CacheClassRec clazz; |
|
240 FTC_MruListClass family_class; |
|
241 |
|
242 } FTC_GCacheClassRec; |
|
243 |
|
244 typedef const FTC_GCacheClassRec* FTC_GCacheClass; |
|
245 |
|
246 #define FTC_GCACHE_CLASS( x ) ((FTC_GCacheClass)(x)) |
|
247 |
|
248 #define FTC_CACHE__GCACHE_CLASS( x ) \ |
|
249 FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class ) |
|
250 #define FTC_CACHE__FAMILY_CLASS( x ) \ |
|
251 ( (FTC_MruListClass)FTC_CACHE__GCACHE_CLASS( x )->family_class ) |
|
252 |
|
253 |
|
254 /* convenience function; use it instead of FTC_Manager_Register_Cache */ |
|
255 FT_LOCAL( FT_Error ) |
|
256 FTC_GCache_New( FTC_Manager manager, |
|
257 FTC_GCacheClass clazz, |
|
258 FTC_GCache *acache ); |
|
259 |
|
260 #ifndef FTC_INLINE |
|
261 FT_LOCAL( FT_Error ) |
|
262 FTC_GCache_Lookup( FTC_GCache cache, |
|
263 FT_PtrDist hash, |
|
264 FT_UInt gindex, |
|
265 FTC_GQuery query, |
|
266 FTC_Node *anode ); |
|
267 #endif |
|
268 |
|
269 |
|
270 /* */ |
|
271 |
|
272 |
|
273 #define FTC_FAMILY_FREE( family, cache ) \ |
|
274 FTC_MruList_Remove( &FTC_GCACHE((cache))->families, \ |
|
275 (FTC_MruNode)(family) ) |
|
276 |
|
277 |
|
278 #ifdef FTC_INLINE |
|
279 |
|
280 #define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ |
|
281 gindex, query, node, error ) \ |
|
282 FT_BEGIN_STMNT \ |
|
283 FTC_GCache _gcache = FTC_GCACHE( cache ); \ |
|
284 FTC_GQuery _gquery = (FTC_GQuery)( query ); \ |
|
285 FTC_MruNode_CompareFunc _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \ |
|
286 FTC_MruNode _mrunode; \ |
|
287 \ |
|
288 \ |
|
289 _gquery->gindex = (gindex); \ |
|
290 \ |
|
291 FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare, \ |
|
292 _mrunode, error ); \ |
|
293 _gquery->family = FTC_FAMILY( _mrunode ); \ |
|
294 if ( !error ) \ |
|
295 { \ |
|
296 FTC_Family _gqfamily = _gquery->family; \ |
|
297 \ |
|
298 \ |
|
299 _gqfamily->num_nodes++; \ |
|
300 \ |
|
301 FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error ); \ |
|
302 \ |
|
303 if ( --_gqfamily->num_nodes == 0 ) \ |
|
304 FTC_FAMILY_FREE( _gqfamily, _gcache ); \ |
|
305 } \ |
|
306 FT_END_STMNT |
|
307 /* */ |
|
308 |
|
309 #else /* !FTC_INLINE */ |
|
310 |
|
311 #define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash, \ |
|
312 gindex, query, node, error ) \ |
|
313 FT_BEGIN_STMNT \ |
|
314 \ |
|
315 error = FTC_GCache_Lookup( FTC_GCACHE( cache ), hash, gindex, \ |
|
316 FTC_GQUERY( query ), &node ); \ |
|
317 \ |
|
318 FT_END_STMNT |
|
319 |
|
320 #endif /* !FTC_INLINE */ |
|
321 |
|
322 |
|
323 FT_END_HEADER |
|
324 |
|
325 |
|
326 #endif /* __FTCGLYPH_H__ */ |
|
327 |
|
328 |
|
329 /* END */ |
|