Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3918 | Serge | 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 |
||
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 */ |